packages feed

roc-cluster-demo (empty) → 0.1.0.0

raw patch · 5 files changed

+175/−0 lines, 5 filesdep +basedep +containersdep +glosssetup-changed

Dependencies added: base, containers, gloss, optparse-applicative, roc-cluster

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Anton Gushcha (c) 2017++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Anton Gushcha nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,5 @@+# roc-cluster-demo++Controls:+- Left click adds new points+- Right click performs clusterization
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ roc-cluster-demo.cabal view
@@ -0,0 +1,29 @@+name:                roc-cluster-demo+version:             0.1.0.0+synopsis:            Gloss interactive demo for roc-cluster package+description:         Demo for displaying operation of ROC online clustering.+homepage:            https://github.com/ncrashed/roc-cluster-demo#readme+license:             BSD3+license-file:        LICENSE+author:              Anton Gushcha+maintainer:          ncrashed@gmail.com+copyright:           2017 Anton Gushcha+category:            Web+build-type:          Simple+cabal-version:       >=1.10+extra-source-files:  README.md++executable roc-cluster-demo+  hs-source-dirs:      src+  main-is:             Main.hs+  default-language:    Haskell2010+  build-depends:+      base                  >= 4.7      && < 5+    , containers            >= 0.5      && < 0.6+    , gloss                 >= 1.10     && < 1.11+    , optparse-applicative  >= 0.13     && < 0.14+    , roc-cluster           >= 0.1      && < 0.2+  default-extensions:+    OverloadedStrings+    RecordWildCards+    ScopedTypeVariables
+ src/Main.hs view
@@ -0,0 +1,109 @@+module Main where++import Data.Cluster.ROC+import Data.Monoid+import Graphics.Gloss.Interface.Pure.Game+import Options.Applicative++import qualified Data.Foldable as F+import qualified Data.Sequence as S+import Debug.Trace++data Vec2 = Vec2 !Float !Float+  deriving (Eq, Show)++instance ClusterSpace Vec2 where+  pointZero = Vec2 0 0+  pointAdd (Vec2 x1 y1) (Vec2 x2 y2) = Vec2 (x1 + x2) (y1 + y2)+  pointScale v (Vec2 x y) = Vec2 (realToFrac v * x) (realToFrac v * y)+  -- gaus kernell with sigma = 1+  pointKernel (Vec2 x1 y1) (Vec2 x2 y2) = realToFrac $ exp ( negate $ 0.5 * ((x2 - x1) ^ 2 + (y2 - y1) ^ 2) )+  pointDistanceSquared x y = 2 - 2 * pointKernel x y+  {-# INLINE pointZero #-}+  {-# INLINE pointAdd #-}+  {-# INLINE pointScale #-}+  {-# INLINE pointKernel #-}+  {-# INLINE pointDistanceSquared #-}++data World = World {+  worldClusters  :: ROCContext Vec2+, worldWidth     :: Float+, worldHeight    :: Float+, worldNewPoints :: S.Seq Vec2+, worldOldPoints :: S.Seq Vec2+}++runClustering :: ROCConfig -> IO ()+runClustering cfg = play display bg fps world render handleEvent update+  where+    width = 800+    height = 800+    display = InWindow "ROC demo" (width, height) (100, 100)+    bg = greyN 0.9+    fps = 60+    world = World (emptyROCContext cfg) (fromIntegral width) (fromIntegral height) mempty mempty++render :: World -> Picture+render World{..} = scaleWorld $ drawOrigin <> drawNewPoints <> drawOldPoints <> drawClusters+  where+    scaleWorld = scale (worldWidth*0.5) (worldHeight*0.5)+    drawOrigin =+         line [(-0.9, 0), (0.9, 0)]+      <> line [(0, -0.9), (0, 0.9)]+    drawNewPoints = F.foldMap (\(Vec2 x y) -> translate x y $ color red $ circleSolid 0.005) worldNewPoints+    drawOldPoints = F.foldMap (\(Vec2 x y) -> translate x y $ color blue $ circleSolid 0.005) worldOldPoints+    drawClusters = F.foldMap drawCluster $ rocPrototypes worldClusters+    drawCluster p = let+      Vec2 x y = prototypeValue p+      r = realToFrac $ 0.1 / (1 + exp (negate $ prototypeWeight p) )+      in translate x y $ circle r <> line [(-0.005, 0), (0.005, 0)] <> line [(0, -0.005), (0, 0.005)]++handleEvent :: Event -> World -> World+handleEvent (EventResize (w, h)) world = world {+    worldWidth = fromIntegral w+  , worldHeight = fromIntegral h+  }+handleEvent (EventKey (MouseButton LeftButton) Down _ (x, y)) world@World{..} = world {+    worldNewPoints = worldNewPoints S.|> Vec2 (2 * x / worldWidth) (2 * y / worldHeight)+  }+handleEvent (EventKey (MouseButton RightButton) Down _ _) world@World{..} = world {+    worldNewPoints = mempty+  , worldOldPoints = worldOldPoints <> worldNewPoints+  , worldClusters = clusterize worldNewPoints worldClusters+  }+handleEvent _ world = world++update :: Float -> World -> World+update = const id++data Options = Options {+  threshold :: Double+, maxClusters :: Int+}++toROCConfig :: Options -> ROCConfig+toROCConfig Options{..} = defaultROCConfig {+    rocThreshold = threshold+  , rocMaxClusters = maxClusters+  }++configParser :: Parser ROCConfig+configParser = fmap toROCConfig $ Options+  <$> option auto (+       long "threshold"+    <> help "Cluster with lower weight will be deleted at post-process step."+    <> value 0.1+    )+  <*> option auto (+       long "maxclusters"+    <> help "Maximum count of allowed clusters."+    <> value 10+    )++main :: IO ()+main = runClustering =<< execParser opts+  where+    opts = info (configParser <**> helper)+      ( fullDesc+     <> progDesc "Run interactive demo for ROC clustering algorithm"+     <> header "roc-cluster-demo - a demo for roc-cluster-demo" )