packages feed

hierarchical-spectral-clustering 0.3.0.1 → 0.4.0.0

raw patch · 3 files changed

+59/−13 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Math.Clustering.Hierarchical.Spectral.Types: GenericClusteringVertex :: !Maybe (Items a) -> !Maybe Double -> GenericClusteringVertex a
+ Math.Clustering.Hierarchical.Spectral.Types: [_distance] :: GenericClusteringVertex a -> !Maybe Double
+ Math.Clustering.Hierarchical.Spectral.Types: [_item] :: GenericClusteringVertex a -> !Maybe (Items a)
+ Math.Clustering.Hierarchical.Spectral.Types: clusteringTreeToGenericClusteringTree :: ClusteringTree a -> GenericClusteringTree a
+ Math.Clustering.Hierarchical.Spectral.Types: data GenericClusteringVertex a
+ Math.Clustering.Hierarchical.Spectral.Types: getClusterItemsGenericTree :: GenericClusteringTree a -> [Items a]
+ Math.Clustering.Hierarchical.Spectral.Types: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Math.Clustering.Hierarchical.Spectral.Types.GenericClusteringVertex a)
+ Math.Clustering.Hierarchical.Spectral.Types: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Math.Clustering.Hierarchical.Spectral.Types.GenericClusteringVertex a)
+ Math.Clustering.Hierarchical.Spectral.Types: instance GHC.Classes.Eq a => GHC.Classes.Eq (Math.Clustering.Hierarchical.Spectral.Types.GenericClusteringVertex a)
+ Math.Clustering.Hierarchical.Spectral.Types: instance GHC.Classes.Ord a => GHC.Classes.Ord (Math.Clustering.Hierarchical.Spectral.Types.GenericClusteringVertex a)
+ Math.Clustering.Hierarchical.Spectral.Types: instance GHC.Generics.Generic (Math.Clustering.Hierarchical.Spectral.Types.GenericClusteringVertex a)
+ Math.Clustering.Hierarchical.Spectral.Types: instance GHC.Read.Read a => GHC.Read.Read (Math.Clustering.Hierarchical.Spectral.Types.GenericClusteringVertex a)
+ Math.Clustering.Hierarchical.Spectral.Types: instance GHC.Show.Show a => GHC.Show.Show (Math.Clustering.Hierarchical.Spectral.Types.GenericClusteringVertex a)
+ Math.Clustering.Hierarchical.Spectral.Types: type GenericClusteringTree a = Tree (GenericClusteringVertex a)

Files

app/Main.hs view
@@ -54,8 +54,9 @@ newtype MinSize    = MinSize { unMinSize :: Int } deriving (Read, Show) newtype NumEigen   = NumEigen { unNumEigen :: Int } deriving (Read, Show) -data ClusteringType = Sparse | Dense deriving (Read, Show)-data Components a = Single (ClusteringTree a) | Multiple [ClusteringTree a]+data ClusteringType = Sparse | Dense | Premade String deriving (Read, Show)+data Components a = Single (GenericClusteringTree a)+                  | Multiple [GenericClusteringTree a]  instance A.ToJSON Q where       toEncoding = A.genericToEncoding A.defaultOptions@@ -67,7 +68,7 @@  -- | Command line arguments data Options = Options { clusteringType :: Maybe String-                                       <?> "([Dense] | Sparse) Method for clustering data."+                                       <?> "([Dense] | Sparse | Premade FILE) Method for clustering data. Premade points to a JSON containing the already made tree to output the leaves as clusters."                        , delimiter      :: Maybe Char                                        <?> "([,] | CHAR) The delimiter of the CSV file. Format is row,column,value with no header."                        , minSize        :: Maybe Int@@ -141,7 +142,8 @@             Dense -> do                 (items, mat) <- readDenseAdjMatrix decodeOpt stdin -                let cluster items = HD.hierarchicalSpectralClusterAdj+                let cluster items = clusteringTreeToGenericClusteringTree+                                  . HD.hierarchicalSpectralClusterAdj                                       eigenGroup'                                       (fmap unNumEigen numEigen')                                       (fmap unMinSize minSize')@@ -158,7 +160,8 @@             Sparse -> do                 (items, mat) <- readEigenSparseAdjMatrix decodeOpt stdin -                let cluster items = HS.hierarchicalSpectralCluster+                let cluster items = clusteringTreeToGenericClusteringTree+                                  . HS.hierarchicalSpectralCluster                                       eigenGroup'                                       (fmap unNumEigen numEigen')                                       (fmap unMinSize minSize')@@ -173,9 +176,12 @@                            $ mat                         else Single $ cluster items mat +            (Premade file) ->+                fmap (either error Single . A.eitherDecode) . B.readFile $ file+     body <- case clusteringTree of         (Single ct) -> do-            let clustering = zip ([1..] :: [Int]) . getClusterItemsTree $ ct+            let clustering = zip ([1..] :: [Int]) . getClusterItemsGenericTree $ ct                 body :: [(T.Text, T.Text)]                 body = concatMap                         (\(!c, xs) -> fmap (\ !x -> (x, showt c)) . V.toList $ xs)@@ -185,13 +191,12 @@                 Nothing                -> return ()                 Just (OutputTree file) -> B.writeFile file                                         . A.encodePretty-                                        . clusteringTreeToDendrogram                                         $ ct              return body         (Multiple cts) -> do             let clustering =-                    fmap (L.over L._2 (zip ([1..] :: [Int]) . getClusterItemsTree))+                    fmap (L.over L._2 (zip ([1..] :: [Int]) . getClusterItemsGenericTree))                         . zip ([1..] :: [Int])                         $ cts                 body :: [(T.Text, T.Text)]@@ -209,19 +214,18 @@             case outputTree' of                 Nothing                -> return ()                 Just (OutputTree file) -> do-                    let getSize :: ClusteringTree a -> Int-                        getSize = sum . fmap V.length . getClusterItemsTree+                    let getSize :: GenericClusteringTree a -> Int+                        getSize = sum . fmap V.length . getClusterItemsGenericTree                         getFileName :: Int -> Int -> String                         getFileName t n =                             uncurry (File.</>)                                 . L.over L._2 (\x -> intercalate "_" ["tree", show t, "size", show n, x])                                 . File.splitFileName                                 $ file-                        write :: (A.ToJSON a) => Int -> ClusteringTree a -> IO ()+                        write :: (A.ToJSON a) => Int -> GenericClusteringTree a -> IO ()                         write t tree = do                             B.writeFile (getFileName t (getSize tree))                                 . A.encodePretty-                                . clusteringTreeToDendrogram                                 $ tree                      mapM_ (uncurry write) . zip [1..] $ cts
hierarchical-spectral-clustering.cabal view
@@ -1,6 +1,6 @@ cabal-version: >=1.10 name: hierarchical-spectral-clustering-version: 0.3.0.1+version: 0.4.0.0 license: GPL-3 license-file: LICENSE copyright: 2019 Gregory W. Schwartz
src/Math/Clustering/Hierarchical/Spectral/Types.hs view
@@ -11,17 +11,22 @@ module Math.Clustering.Hierarchical.Spectral.Types     ( ClusteringTree (..)     , ClusteringVertex (..)+    , GenericClusteringTree (..)+    , GenericClusteringVertex (..)     , EigenGroup (..)     , clusteringTreeToDendrogram     , clusteringTreeToDendrogramCumulative+    , clusteringTreeToGenericClusteringTree     , getClusterItemsDend     , getClusterItemsTree+    , getClusterItemsGenericTree     , Q (..)     , NumEigen (..)     ) where  -- Remote import Data.Clustering.Hierarchical (Dendrogram (..))+import Data.Maybe (catMaybes) import Data.Monoid ((<>)) import Data.Tree (Tree (..)) import GHC.Generics (Generic)@@ -35,6 +40,7 @@  type Items a         = V.Vector a type ClusteringTree a = Tree (ClusteringVertex a)+type GenericClusteringTree a = Tree (GenericClusteringVertex a) type NumEigen = Int  data EigenGroup = SignGroup | KMeansGroup deriving (Read, Show, Generic)@@ -44,6 +50,11 @@     , _ngMod            :: !Q     } deriving (Eq, Ord, Read, Show, Generic) +data GenericClusteringVertex a = GenericClusteringVertex+    { _item :: !(Maybe (Items a))+    , _distance :: !(Maybe Double)+    } deriving (Eq, Ord, Read, Show, Generic)+ -- | Convert a ClusteringTree to a Dendrogram. Modularity is the distance. clusteringTreeToDendrogram :: ClusteringTree a -> Dendrogram (Items a) clusteringTreeToDendrogram = go@@ -74,6 +85,29 @@             <> (show $ length xs)             <> " children. Requires two or none." +-- | Convert a ClusteringTree to a GenericClusteringVertex tree (more+-- standardized for our purposes).+clusteringTreeToGenericClusteringTree :: ClusteringTree a+                                      -> GenericClusteringTree a+clusteringTreeToGenericClusteringTree = go+  where+    go (Node { rootLabel = !n, subForest = []}) =+      Node { rootLabel = ( GenericClusteringVertex+                             { _item = Just $ _clusteringItems n+                             , _distance = Nothing+                             }+                         )+           , subForest = []+           }+    go (Node { rootLabel = !n, subForest = xs }) =+      Node { rootLabel = ( GenericClusteringVertex+                            { _item = Nothing+                            , _distance = Just . unQ . _ngMod $ n+                            }+                         )+           , subForest = fmap go xs+           }+ -- | Gather clusters (leaves) from the dendrogram. getClusterItemsDend :: Foldable t => t (Items a) -> [Items a] getClusterItemsDend = F.toList@@ -81,6 +115,10 @@ -- | Gather clusters (leaves) from the tree. getClusterItemsTree :: ClusteringTree a -> [Items a] getClusterItemsTree = fmap _clusteringItems . leaves+                    +-- | Gather clusters (leaves) from the generic tree.+getClusterItemsGenericTree :: GenericClusteringTree a -> [Items a]+getClusterItemsGenericTree = catMaybes . fmap _item . leaves  deriving instance (Read a) => Read (Dendrogram a) deriving instance Generic (Dendrogram a)@@ -88,3 +126,7 @@ instance (A.ToJSON a) => A.ToJSON (Dendrogram a) where     toEncoding = A.genericToEncoding A.defaultOptions instance (A.FromJSON a) => A.FromJSON (Dendrogram a)++instance (A.ToJSON a) => A.ToJSON (GenericClusteringVertex a) where+    toEncoding = A.genericToEncoding A.defaultOptions+instance (A.FromJSON a) => A.FromJSON (GenericClusteringVertex a)