Commit d584aed7 authored by Alexandre Delanoë's avatar Alexandre Delanoë

[FEAT] bridgeness work

parent 3a533287
...@@ -30,6 +30,7 @@ module Gargantext.Prelude ...@@ -30,6 +30,7 @@ module Gargantext.Prelude
, sortWith , sortWith
, module Prelude , module Prelude
, MonadBase(..) , MonadBase(..)
, Map2 , lookup2
) )
where where
...@@ -37,6 +38,7 @@ import Control.Monad.Base (MonadBase(..)) ...@@ -37,6 +38,7 @@ import Control.Monad.Base (MonadBase(..))
import GHC.Exts (sortWith) import GHC.Exts (sortWith)
import GHC.Err.Located (undefined) import GHC.Err.Located (undefined)
import GHC.Real (round) import GHC.Real (round)
import Data.Map (Map, lookup)
import Data.Maybe (isJust, fromJust, maybe) import Data.Maybe (isJust, fromJust, maybe)
import Data.Text (Text) import Data.Text (Text)
import Protolude ( Bool(True, False), Int, Int64, Double, Integer import Protolude ( Bool(True, False), Int, Int64, Double, Integer
...@@ -298,9 +300,25 @@ movingAverage steps xs = map mean $ chunkAlong steps 1 xs ...@@ -298,9 +300,25 @@ movingAverage steps xs = map mean $ chunkAlong steps 1 xs
ma :: [Double] -> [Double] ma :: [Double] -> [Double]
ma = movingAverage 3 ma = movingAverage 3
----------------------------------------------------------------------- -----------------------------------------------------------------------
fib :: Int -> Int fib :: Int -> Int
fib 0 = 0 fib 0 = 0
fib 1 = 1 fib 1 = 1
fib n = fib (n-1) + fib (n-2) fib n = fib (n-1) + fib (n-2)
-----------------------------------------------------------------------
--- Map in Map = Map2
-- To avoid Map (a,a) b
type Map2 a b = Map a (Map a b)
lookup2 :: Ord a
=> a
-> a
-> Map2 a b
-> Maybe b
lookup2 a b m = do
m' <- lookup a m
lookup b m'
...@@ -10,20 +10,26 @@ Portability : POSIX ...@@ -10,20 +10,26 @@ Portability : POSIX
Let be a graph with partitions (from Louvain algo), Bridgeness uniformly Let be a graph with partitions (from Louvain algo), Bridgeness uniformly
filters inter-communities links. filters inter-communities links.
TODO rewrite Bridgeness with "equivalence structurale" metrics TODO rewrite Bridgeness with "equivalence structurale" metrics (Confluence)
TODO use Map LouvainNodeId (Map LouvainNodeId)
-} -}
{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE NoImplicitPrelude #-}
module Gargantext.Viz.Graph.Bridgeness (bridgeness) module Gargantext.Viz.Graph.Bridgeness (bridgeness)
where where
--import GHC.Base (Semigroup)
import Data.Ord (Down(..))
import Gargantext.Prelude import Gargantext.Prelude
--import Data.Tuple.Extra (swap) import Data.Map (Map, fromListWith, lookup, fromList, toList, mapWithKey, elems)
--import Gargantext.Viz.Graph
import Data.Map (Map, fromListWith, lookup, fromList, delete, toList, mapKeys, mapWithKey, elems)
import qualified Data.Map as DM import qualified Data.Map as DM
import Data.Maybe (fromJust) import Data.Maybe (catMaybes)
import Data.List (concat, sortOn) import Data.List (concat, sortOn)
import Data.Graph.Clustering.Louvain.Utils (LouvainNode(..)) import Data.Graph.Clustering.Louvain.Utils (LouvainNode(..))
...@@ -45,34 +51,36 @@ bridgeness b ns = DM.fromList ...@@ -45,34 +51,36 @@ bridgeness b ns = DM.fromList
. filterComs b . filterComs b
. groupEdges (nodeId2comId ns) . groupEdges (nodeId2comId ns)
nodeId2comId :: [LouvainNode] -> Map LouvainNodeId CommunityId nodeId2comId :: [LouvainNode] -> Map LouvainNodeId CommunityId
nodeId2comId ns = fromList [ (nId,cId) | LouvainNode nId cId <- ns] nodeId2comId ns = fromList [ (nId,cId) | LouvainNode nId cId <- ns]
groupEdges :: Map LouvainNodeId CommunityId groupEdges :: Map LouvainNodeId CommunityId
-> Map (LouvainNodeId, LouvainNodeId) Double -> Map (LouvainNodeId, LouvainNodeId) Double
-> Map (CommunityId, CommunityId) [((LouvainNodeId, LouvainNodeId), Double)] -> Map (CommunityId, CommunityId) [((LouvainNodeId, LouvainNodeId), Double)]
groupEdges m = mapKeys fromJust groupEdges m = fromListWith (<>)
. delete Nothing . catMaybes
. fromListWith (<>)
. map (\((n1,n2), d) . map (\((n1,n2), d)
-> ((,) <$> lookup n1 m -> let
<*> lookup n2 m n1n2_m = (,) <$> lookup n1 m <*> lookup n2 m
, [((n1,n2),d)] n1n2_d = Just [((n1,n2),d)]
) in (,) <$> n1n2_m <*> n1n2_d
) )
. toList . toList
-- | TODO : sortOn Confluence
filterComs :: Bridgeness filterComs :: Bridgeness
-> Map (CommunityId, CommunityId) [((LouvainNodeId, LouvainNodeId), Double)] -> Map (CommunityId, CommunityId) [((LouvainNodeId, LouvainNodeId), Double)]
-> Map (CommunityId, CommunityId) [((LouvainNodeId, LouvainNodeId), Double)] -> Map (CommunityId, CommunityId) [((LouvainNodeId, LouvainNodeId), Double)]
filterComs b m = mapWithKey filter' m filterComs b m = mapWithKey filter' m
where where
filter' (c1,c2) a = case c1 == c2 of filter' (c1,c2) a
True -> a | c1 == c2 = a
False -> take n $ sortOn snd a | otherwise = take n $ sortOn (Down . snd) a
where where
n = round $ b * a' / t n = round $ 100 * b * a' / t
a'= fromIntegral $ length a a'= fromIntegral $ length a
t = fromIntegral $ length $ concat $ elems m t = fromIntegral $ length $ concat $ elems m
...@@ -15,6 +15,7 @@ Portability : POSIX ...@@ -15,6 +15,7 @@ Portability : POSIX
module Gargantext.Viz.Graph.Tools module Gargantext.Viz.Graph.Tools
where where
import Debug.Trace (trace)
import Data.Graph.Clustering.Louvain.Utils (LouvainNode(..)) import Data.Graph.Clustering.Louvain.Utils (LouvainNode(..))
-- import Data.Graph.Clustering.Louvain (hLouvain, {-iLouvainMap-}) -- import Data.Graph.Clustering.Louvain (hLouvain, {-iLouvainMap-})
import Data.Graph.Clustering.Louvain.CplusPlus (cLouvain) import Data.Graph.Clustering.Louvain.CplusPlus (cLouvain)
...@@ -71,14 +72,14 @@ cooc2graph threshold myCooc = do ...@@ -71,14 +72,14 @@ cooc2graph threshold myCooc = do
partitions <- if (Map.size distanceMap > 0) partitions <- if (Map.size distanceMap > 0)
--then iLouvainMap 100 10 distanceMap -- then iLouvainMap 100 10 distanceMap
-- then hLouvain distanceMap -- then hLouvain distanceMap
then cLouvain level distanceMap then cLouvain level distanceMap
else panic "Text.Flow: DistanceMap is empty" else panic "Text.Flow: DistanceMap is empty"
let let
bridgeness' = distanceMap -- bridgeness' = distanceMap
_bridgeness' = bridgeness rivers partitions distanceMap bridgeness' = trace ("Rivers: " <> show rivers) $ bridgeness rivers partitions distanceMap
confluence' = confluence (Map.keys bridgeness') 3 True False confluence' = confluence (Map.keys bridgeness') 3 True False
pure $ data2graph (Map.toList ti) myCooc' bridgeness' confluence' partitions pure $ data2graph (Map.toList ti) myCooc' bridgeness' confluence' partitions
......
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