Commit 58e1e578 authored by Grégoire Locqueville's avatar Grégoire Locqueville

Fix spinglass functions

Spinglass functions would output incoherent clusters when the input graph
was nonconnected.
parent a36d62b5
...@@ -627,7 +627,6 @@ library ...@@ -627,7 +627,6 @@ library
, servant-websockets >= 2.0.0 && < 2.1 , servant-websockets >= 2.0.0 && < 2.1
, servant-xml-conduit ^>= 0.1.0.4 , servant-xml-conduit ^>= 0.1.0.4
, shelly >= 1.9 && < 2 , shelly >= 1.9 && < 2
, singletons ^>= 3.0.2
, singletons-th >= 3.1 && < 3.3 , singletons-th >= 3.1 && < 3.3
, smtp-mail >= 0.3.0.0 , smtp-mail >= 0.3.0.0
, split >= 0.2.3.4 , split >= 0.2.3.4
......
...@@ -16,8 +16,6 @@ module Gargantext.Core.Viz.Graph.Tools.IGraph ...@@ -16,8 +16,6 @@ module Gargantext.Core.Viz.Graph.Tools.IGraph
where where
import Data.Serialize import Data.Serialize
import Data.Singletons (SingI)
import Gargantext.Core.Viz.Graph.Index
import Graph.Types (ClusterNode(..)) import Graph.Types (ClusterNode(..))
import IGraph hiding (mkGraph, neighbors, edges, nodes, Node, Graph) import IGraph hiding (mkGraph, neighbors, edges, nodes, Node, Graph)
import Protolude import Protolude
...@@ -63,46 +61,34 @@ type Seed = Int ...@@ -63,46 +61,34 @@ type Seed = Int
spinglass :: Seed -> Map (Int, Int) Double -> IO [ClusterNode] spinglass :: Seed -> Map (Int, Int) Double -> IO [ClusterNode]
spinglass s g = toClusterNode spinglass s g = toClusterNode
<$> map catMaybes
<$> map (map (\n -> Map.lookup n fromI))
<$> List.concat <$> List.concat
<$> mapM (partitions_spinglass' s) g' <$> mapM (partitions_spinglass' s) g'
where where
-- Not connected components of the graph make crash spinglass -- Non-connected graphs make spinglass crash
g' = IG.decompose $ mkGraphUfromEdges g' = IG.decompose -- decompose graph into connected components
$ Map.keys $ edgeList2UGraph -- convert into IGraph type
$ toIndex toI g $ Map.keys g -- retrieve edges in the form of `(Int, Int)`
(toI, fromI) = createIndices g
spinglass' :: Seed -> Map (Int, Int) Double -> IO [Set Int] spinglass' :: Seed -> Map (Int, Int) Double -> IO [Set Int]
spinglass' s g = map Set.fromList spinglass' s g = map Set.fromList
<$> map catMaybes
<$> map (map (\n -> Map.lookup n fromI))
<$> List.concat <$> List.concat
<$> mapM (partitions_spinglass' s) g' <$> mapM (partitions_spinglass' s) g'
where where
-- Not connected components of the graph make crash spinglass -- Non-connected graphs make spinglass crash
g' = IG.decompose $ mkGraphUfromEdges g' = IG.decompose -- decompose graph into connected components
$ Map.keys $ edgeList2UGraph -- convert into IGraph type
$ toIndex toI g $ Map.keys g -- retrieve edges in the form of `(Int, Int)`
(toI, fromI) = createIndices g
-- | Tools to analyze graphs -- | Tools to analyze graphs
partitions_spinglass' :: (Serialize v, Serialize e) partitions_spinglass' :: (Serialize v, Serialize e, Show v)
=> Seed -> IG.Graph 'U v e -> IO [[Int]] => Seed -> IG.Graph 'U v e -> IO [[v]]
partitions_spinglass' s g = do partitions_spinglass' s g = do
gen <- IG.withSeed s pure gen <- IG.withSeed s pure
res <- IG.findCommunity g Nothing Nothing IG.spinglass gen rawClusters <- IG.findCommunity g Nothing Nothing IG.spinglass gen
-- res <- IG.findCommunity g Nothing Nothing IG.leiden gen let clusterLabels = (fmap . fmap) (IG.nodeLab g) rawClusters
-- res <- IG.findCommunity g Nothing Nothing IG.infomap gen saveAsFileDebug "/tmp/res" clusterLabels
saveAsFileDebug "/tmp/res" res pure clusterLabels
pure res
toClusterNode :: [[Int]] -> [ClusterNode] toClusterNode :: [[Int]] -> [ClusterNode]
...@@ -110,20 +96,17 @@ toClusterNode ns = List.concat ...@@ -110,20 +96,17 @@ toClusterNode ns = List.concat
$ map (\(cId, ns') -> map (\n -> ClusterNode n cId) ns') $ map (\(cId, ns') -> map (\n -> ClusterNode n cId) ns')
$ List.zip [1..] ns $ List.zip [1..] ns
------------------------------------------------------------------ -- | Make an undirected IGraph graph from a list of edges between `Int`s.
mkGraph :: (SingI d, Ord v, -- The output graph's vertices are labeled with the original `Int`s, and the
Serialize v, Serialize e) => -- edges are not labeled.
[v] -> [LEdge e] -> IG.Graph d v e edgeList2UGraph :: [(Int, Int)] -> IG.Graph 'U Int ()
mkGraph = IG.mkGraph edgeList2UGraph edgeList =
-- We're not using `IG.mkGraph` because of the following ticket:
-- https://gitlab.iscpif.fr/gargantext/haskell-igraph/issues/4
IG.fromLabeledEdges $ fmap (\edge -> (edge, ())) $ edgeList
------------------------------------------------------------------
mkGraphUfromEdges :: [(Int, Int)] -> Graph_Undirected mkGraphUfromEdges :: [(Int, Int)] -> Graph_Undirected
mkGraphUfromEdges es = mkGraph (List.replicate n ()) $ zip es $ repeat () mkGraphUfromEdges es = IG.mkGraph (List.replicate n ()) $ zip es $ repeat ()
where where
(a,b) = List.unzip es (a,b) = List.unzip es
n = List.length (List.nub $ a <> b) n = List.length (List.nub $ a <> b)
{-
mkGraphDfromEdges :: [(Int, Int)] -> Graph_Directed
mkGraphDfromEdges = undefined
-}
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