1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{-|
Module : Gargantext.Core.Methods.Similarities
Description :
Copyright : (c) CNRS, 2017-Present
License : AGPL + CECILL v3
Maintainer : team@gargantext.org
Stability : experimental
Portability : POSIX
Motivation and definition of the @Conditional@ distance.
-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE Strict #-}
module Gargantext.Core.Methods.Similarities.Conditional
where
import Control.DeepSeq (NFData)
import Control.Parallel.Strategies (parList, rdeepseq, using)
import Data.Hashable (Hashable)
import Data.List (unzip)
import Data.Maybe (catMaybes)
import Gargantext.Prelude
import Gargantext.Core.Viz.Graph.Utils (getMax)
import qualified Data.HashMap.Strict as Map
import qualified Data.Set as Set
type HashMap = Map.HashMap
------------------------------------------------------------------------
-- First version as first implementation
-- - qualitatively verified
-- - parallized as main optimization
conditional :: (Ord a, Hashable a, NFData a)
=> HashMap (a,a) Int
-> HashMap (a,a) Double
conditional m' = Map.fromList $ ((catMaybes results') `using` parList rdeepseq)
where
results' = [ let
ij = (/) <$> Map.lookup (i,j) m <*> Map.lookup (i,i) m
ji = (/) <$> Map.lookup (j,i) m <*> Map.lookup (j,j) m
in getMax (i,j) ij ji
| i <- keys
, j <- keys
, i < j
]
-- Converting from Int to Double
m = Map.map fromIntegral m'
-- Get the matrix coordinates, removing duplicates
keys = Set.toList $ Set.fromList (x <> y)
(x,y) = unzip $ Map.keys m