packages feed

numhask-histogram 0.1.3.0 → 0.2.0

raw patch · 4 files changed

+55/−67 lines, 4 filesdep +numhask-spacedep −numhask-preludedep −numhask-range

Dependencies added: numhask-space

Dependencies removed: numhask-prelude, numhask-range

Files

numhask-histogram.cabal view
@@ -1,11 +1,5 @@--- This file has been generated from package.yaml by hpack version 0.28.2.------ see: https://github.com/sol/hpack------ hash: 06f538b0715c38391805b7491f4212890c30f2d6111828cac2bb0d2db59602f5- name:           numhask-histogram-version:        0.1.3.0+version:        0.2.0 synopsis:       See readme.md description:    See readme.md for description. category:       project@@ -17,7 +11,7 @@ license:        BSD3 license-file:   LICENSE build-type:     Simple-cabal-version:  >= 1.10+cabal-version:  1.12 extra-source-files:     stack.yaml @@ -28,14 +22,13 @@ library   hs-source-dirs:       src-  default-extensions: NegativeLiterals NoImplicitPrelude OverloadedStrings UnicodeSyntax+  default-extensions: NegativeLiterals OverloadedStrings UnicodeSyntax   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -Wall   build-depends:       base >=4.7 && <5     , containers     , foldl-    , numhask-prelude >=0.1.0.1-    , numhask-range >=0.2.3.0+    , numhask-space     , tdigest   exposed-modules:       NumHask.Histogram@@ -53,7 +46,6 @@   build-depends:       base >=4.7 && <5     , doctest-    , numhask-prelude >=0.0.5.1   other-modules:       Paths_numhask_histogram   default-language: Haskell2010
src/NumHask/Histogram.hs view
@@ -1,34 +1,37 @@ {-# LANGUAGE DataKinds #-}-{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TupleSections #-} {-# OPTIONS_GHC -Wall #-}  module NumHask.Histogram-  ( Histogram(..)-  , DealOvers(..)-  , fill-  , regular-  , makeRects-  , regularQuantiles-  , quantileFold-  , fromQuantiles-  , freq-  ) where+  ( Histogram (..),+    DealOvers (..),+    fill,+    regular,+    makeRects,+    regularQuantiles,+    quantileFold,+    fromQuantiles,+    freq,+  )+where -import Data.TDigest-import NumHask.Prelude-import NumHask.Range-import NumHask.Rect-import NumHask.Space-import qualified Data.Map as Map import qualified Control.Foldl as L import qualified Data.List+import qualified Data.Map as Map+import Data.Maybe+import Data.TDigest+import NumHask.Space+import Prelude  -- | a Histogram is a list of contiguous boundaries (a boundary being the lower edge of one bucket and the upper edge of another), and a count for each bucket -- Overs and Unders are counted in key=0 and key=length cut-data Histogram = Histogram-   { cuts   :: [Double] -- bucket boundaries-   , values :: Map.Map Int Double -- bucket counts-   } deriving (Show, Eq)+data Histogram+  = Histogram+      { cuts :: [Double], -- bucket boundaries+        values :: Map.Map Int Double -- bucket counts+      }+  deriving (Show, Eq)  -- | whether or not to ignore unders and overs data DealOvers = IgnoreOvers | IncludeOvers Double@@ -39,52 +42,51 @@ fill :: (Functor f, Foldable f) => [Double] -> f Double -> Histogram fill cs xs = Histogram cs (histMap cs xs)   where-    histMap cs' xs' = L.fold count $+    histMap cs' xs' =+      L.fold count $         (\x -> L.fold countBool (fmap (x >) cs')) <$> xs'-    count = L.premap (\x -> (x,1.0)) countW-    countBool = L.Fold (\x a -> x + if a then 1 else 0) 0 identity-    countW = L.Fold (\x (a,w) -> Map.insertWith (+) a w x) Map.empty identity+    count = L.premap (,1.0) countW+    countBool = L.Fold (\x a -> x + if a then 1 else 0) 0 id+    countW = L.Fold (\x (a, w) -> Map.insertWith (+) a w x) Map.empty id  -- | make a histogram using n equally spaced cuts over the entire range of the data -- >>> regular 4 [0..100] -- Histogram {cuts = [0.0,25.0,50.0,75.0,100.0], values = fromList [(0,1.0),(1,25.0),(2,25.0),(3,25.0),(4,25.0)]}--- regular :: Int -> [Double] -> Histogram regular n xs = fill cs xs   where-    cs = grid OuterPos (space xs :: Range Double) n+    cs = grid OuterPos (space1 xs :: Range Double) n  -- | transform a Histogram to Rects -- >>> makeRects IgnoreOvers (regular 4 [0..100]) -- [Rect 0.0 25.0 0.0 0.25,Rect 25.0 50.0 0.0 0.25,Rect 50.0 75.0 0.0 0.25,Rect 75.0 100.0 0.0 0.25]--- makeRects :: DealOvers -> Histogram -> [Rect Double] makeRects o (Histogram cs counts) = Data.List.zipWith4 Rect x z y w'   where     y = repeat 0-    w = zipWith (/)-        ((\x' -> Map.findWithDefault 0 x' counts) <$> [f..l])+    w =+      zipWith+        (/)+        ((\x' -> Map.findWithDefault 0 x' counts) <$> [f .. l])         (zipWith (-) z x)     f = case o of-          IgnoreOvers -> 1-          IncludeOvers _ -> 0+      IgnoreOvers -> 1+      IncludeOvers _ -> 0     l = case o of-          IgnoreOvers -> length cs - 1-          IncludeOvers _ -> length cs-    w' = (/sum w) <$> w+      IgnoreOvers -> length cs - 1+      IncludeOvers _ -> length cs+    w' = (/ sum w) <$> w     x = case o of-          IgnoreOvers -> cs-          IncludeOvers outw ->-            [Data.List.head cs - outw] <>-            cs <>-            [Data.List.last cs + outw]+      IgnoreOvers -> cs+      IncludeOvers outw ->+        [Data.List.head cs - outw]+          <> cs+          <> [Data.List.last cs + outw]     z = drop 1 x - -- | approx regular n-quantiles -- >>> regularQuantiles 4 [0..100] -- [0.0,24.75,50.0,75.25,100.0]--- regularQuantiles :: Double -> [Double] -> [Double] regularQuantiles n = L.fold (quantileFold qs)   where@@ -96,23 +98,21 @@   where     step x a = Data.TDigest.insert a x     begin = tdigest ([] :: [Double]) :: TDigest 25-    done x = fromMaybe nan . (`quantile` compress x) <$> qs+    done x = fromMaybe (0 / 0) . (`quantile` compress x) <$> qs  -- | take a specification of quantiles and make a Histogram -- >>> fromQuantiles [0,0.25,0.5,0.75,1] (regularQuantiles 4 [0..100]) -- Histogram {cuts = [0.0,24.75,50.0,75.25,100.0], values = fromList [(1,0.25),(2,0.25),(3,0.25),(4,0.25)]}--- fromQuantiles :: [Double] -> [Double] -> Histogram-fromQuantiles qs xs = Histogram xs (Map.fromList $ zip [1..] (diffq qs))+fromQuantiles qs xs = Histogram xs (Map.fromList $ zip [1 ..] (diffq qs))   where     diffq [] = []     diffq [_] = []-    diffq (x:xs') = L.fold (L.Fold step (x,[]) (reverse . snd)) xs'-    step (a0,xs') a = (a,(a-a0):xs')+    diffq (x : xs') = L.fold (L.Fold step (x, []) (reverse . snd)) xs'+    step (a0, xs') a = (a, (a - a0) : xs')  -- | normalize a histogram so that sum values = one -- >>> freq $ fill [0,50,100] [1..100] -- Histogram {cuts = [0.0,50.0,100.0], values = fromList [(1,0.5),(2,0.5)]}--- freq :: Histogram -> Histogram freq (Histogram cs vs) = Histogram cs $ Map.map (* recip (sum vs)) vs
stack.yaml view
@@ -1,13 +1,10 @@-resolver: nightly-2018-05-28+resolver: lts-14.13  packages:   - .-  - ../numhask-range  extra-deps:   - tdigest-0.2-  - numhask-prelude-0.1.0.1-  - numhask-0.2.3.0-  - numhask-test-0.1.0.0+  - numhask-space-0.2.0  allow-newer: true
test/test.hs view
@@ -1,9 +1,8 @@-{-# LANGUAGE NoImplicitPrelude #-} {-# OPTIONS_GHC -Wall #-}  module Main where -import NumHask.Prelude+import Prelude import Test.DocTest  main :: IO ()