HLearn-distributions-1.1.0.1: src/HLearn/Models/Distributions/Visualization/Graphviz.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
-- | Displays Multivariate dependencies
module HLearn.Models.Distributions.Visualization.Graphviz
( MultivariateLabels (..)
, MarkovNetwork (..)
)
where
import HLearn.Algebra
import HLearn.Models.Distributions.Multivariate.Interface
import HLearn.Models.Distributions.Multivariate.Internal.CatContainer
import HLearn.Models.Distributions.Multivariate.Internal.Container
import HLearn.Models.Distributions.Multivariate.Internal.TypeLens
import Data.GraphViz.Exception
import Data.GraphViz hiding (graphToDot)
import Data.GraphViz.Attributes.Complete{-( Attribute(RankDir, Splines, FontName)
, RankDir(FromLeft), EdgeType(SplineEdges))-}
import Control.Arrow(second)
import GHC.TypeLits
-------------------------------------------------------------------------------
-- clases
class (Trainable datatype) => MultivariateLabels datatype where
getLabels :: datatype -> [String]
class (MultivariateLabels (Datapoint dist)) => MarkovNetwork dist where
graphL :: dist -> [String] -> [(String,[String])]
plotNetwork :: FilePath -> dist -> IO Bool
plotNetwork file dist = graphToDotPng file $ graphL dist $ getLabels (undefined :: Datapoint dist)
-------------------------------------------------------------------------------
-- instances
instance
( MultivariateLabels datapoint
) => MarkovNetwork (Multivariate datapoint '[] prob)
where
graphL _ labels = []
instance
( MultivariateLabels datapoint
, MarkovNetwork (Multivariate datapoint xs prob)
) => MarkovNetwork (Multivariate datapoint ( ('[]) ': xs) prob)
where
graphL _ labels = graphL (undefined :: Multivariate datapoint xs prob) labels
instance
( MultivariateLabels datapoint
, MarkovNetwork (Multivariate datapoint ( ys ': xs) prob)
) => MarkovNetwork (Multivariate datapoint ( (Ignore' label ': ys) ': xs) prob)
where
graphL _ labels = (graphL (undefined :: Multivariate datapoint ( ys ': xs) prob) (tail labels))
instance
( MultivariateLabels datapoint
, MarkovNetwork (Multivariate datapoint ( ys ': xs) prob)
) => MarkovNetwork (Multivariate datapoint ( (CatContainer label ': ys) ': xs) prob)
where
graphL _ labels = (head labels, tail labels)
: (graphL (undefined :: Multivariate datapoint ( ys ': xs) prob) (tail labels))
instance
( MultivariateLabels datapoint
, MarkovNetwork (Multivariate datapoint (ys ': xs) prob)
) => MarkovNetwork (Multivariate datapoint ( (Container dist label ': ys) ': xs) prob)
where
graphL _ l = (head l,[]):(graphL (undefined::Multivariate datapoint (ys ': xs) prob) (tail l))
instance
( MultivariateLabels datapoint
, SingI (Length labelL)
, MarkovNetwork (Multivariate datapoint ( ys ': xs) prob)
) => MarkovNetwork (Multivariate datapoint ( (MultiContainer dist (labelL:: [*]) ': ys) ': xs) prob)
where
graphL _ l = go (take n l) ++ (graphL (undefined :: Multivariate datapoint ( ys ': xs ) prob) $ drop n l)
where
go [] = []
go (x:xs) = (x,xs):(go xs)
n = fromIntegral $ fromSing $ (sing :: Sing (Length labelL))
-------------------------------------------------------------------------------
-- Graphviz helpers
---------------------------------------
-- These functions are taken from the graphviz tutorial at:
-- http://ivanmiljenovic.wordpress.com/2011/10/16/graphviz-in-vacuum/
graphToDot :: (Ord a) => [(a, [a])] -> DotGraph a
graphToDot = graphToDotParams vacuumParams
graphToDotParams :: (Ord a, Ord cl) => GraphvizParams a () () cl l -> [(a, [a])] -> DotGraph a
graphToDotParams params nes = graphElemsToDot params ns es
where
ns = map (second $ const ()) nes
es = concatMap mkEs nes
mkEs (f,ts) = map (\t -> (f,t,())) ts
------------------------------------------------
vacuumParams :: GraphvizParams a () () () ()
vacuumParams = defaultParams { globalAttributes = gStyle }
gStyle :: [GlobalAttributes]
gStyle = [ GraphAttrs [RankDir FromLeft, {-Splines SplineEdges, -}FontName "courier", Layout Circo]
, NodeAttrs [textLabel "\\N", shape PlainText, fontColor Black, Shape Ellipse, style filled, fillColor AliceBlue, penWidth 2, color Navy]
, EdgeAttrs [color Black, Dir NoDir]
]
graphToDotPng :: FilePath -> [(String,[String])] -> IO Bool
graphToDotPng fpre g = handle (\(e::GraphvizException) -> return False)
$ addExtension (runGraphviz (graphToDot g)) Png fpre >> return True