mealy 0.5.0.0 → 0.5.0.1
raw patch · 5 files changed
+216/−58 lines, 5 filesdep +clockdep +deepseqdep +formatndep ~basedep ~containersdep ~doctest-parallelnew-component:exe:mealy-perfPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: clock, deepseq, formatn, mtl, optics-core, optparse-applicative, perf, time
Dependency ranges changed: base, containers, doctest-parallel, numhask
API changes (from Hackage documentation)
- Data.Mealy: pattern M :: (a -> c) -> (c -> a -> c) -> (c -> b) -> Mealy a b
+ Data.Mealy: pattern M :: forall a b c. () => (a -> c) -> (c -> a -> c) -> (c -> b) -> Mealy a b
+ Data.Mealy.Quantiles: OnlineTDigest :: TDigest 25 -> Int -> Double -> OnlineTDigest
+ Data.Mealy.Quantiles: [tdN] :: OnlineTDigest -> Int
+ Data.Mealy.Quantiles: [tdRate] :: OnlineTDigest -> Double
+ Data.Mealy.Quantiles: [td] :: OnlineTDigest -> TDigest 25
+ Data.Mealy.Quantiles: data OnlineTDigest
+ Data.Mealy.Quantiles: emptyOnlineTDigest :: Double -> OnlineTDigest
+ Data.Mealy.Quantiles: onlineCompress :: OnlineTDigest -> OnlineTDigest
+ Data.Mealy.Quantiles: onlineForceCompress :: OnlineTDigest -> OnlineTDigest
+ Data.Mealy.Quantiles: onlineInsert :: Double -> OnlineTDigest -> OnlineTDigest
- Data.Mealy: alpha :: (ExpField a, KnownNat n, Eq a) => a -> Mealy (Array '[n] a, a) a
+ Data.Mealy: alpha :: forall a (n :: Nat). (ExpField a, KnownNat n, Eq a) => a -> Mealy (Array '[n] a, a) a
- Data.Mealy: beta :: (ExpField a, KnownNat n, Eq a) => a -> Mealy (Array '[n] a, a) (Array '[n] a)
+ Data.Mealy: beta :: forall a (n :: Nat). (ExpField a, KnownNat n, Eq a) => a -> Mealy (Array '[n] a, a) (Array '[n] a)
- Data.Mealy: reg :: (ExpField a, KnownNat n, Eq a) => a -> Mealy (Array '[n] a, a) (Array '[n] a, a)
+ Data.Mealy: reg :: forall a (n :: Nat). (ExpField a, KnownNat n, Eq a) => a -> Mealy (Array '[n] a, a) (Array '[n] a, a)
Files
- mealy.cabal +108/−55
- readme.org +1/−1
- src/Data/Mealy.hs +1/−2
- src/Data/Mealy/Quantiles.hs +5/−0
- test/mealy-perf.hs +101/−0
mealy.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: mealy-version: 0.5.0.0+version: 0.5.0.1 license: BSD-3-Clause license-file: LICENSE copyright: Tony Day (c) 2013@@ -11,73 +11,126 @@ bug-reports: https://github.com/tonyday567/mealy/issues synopsis: Mealy machines for processing time-series and ordered data. description:-- @mealy@ reimagines statistics as a [mealy machine](https://en.wikipedia.org/wiki/Mealy_machine) processing data with some form of order such as time-series data. The 'Mealy', with the help of a decay function specifying the relative weights of recent values versus older value, can be treated as a compression or summary of the data stream into 'current state.'- Mealies are highly polymorphic, situated at a busy crossroad of theory and practice, and lend themselves to ergonmic, compact and realistic representations of a wide range of online phenomena.+ @mealy@ reimagines statistics as a [mealy machine](https://en.wikipedia.org/wiki/Mealy_machine) processing data with some form of order such as time-series data. The 'Mealy', with the help of a decay function specifying the relative weights of recent values versus older value, can be treated as a compression or summary of the data stream into 'current state.'+ Mealies are highly polymorphic, situated at a busy crossroad of theory and practice, and lend themselves to ergonmic, compact and realistic representations of a wide range of online phenomena. - == Usage+ == Usage - >>> import Mealy+ >>> import Mealy - >>> fold ((,) <$> ma 0.9 <*> std 0.9) [1..100]- (91.00265621044142,9.472822805289121)+ >>> fold ((,) <$> ma 0.9 <*> std 0.9) [1..100]+ (91.00265621044142,9.472822805289121) build-type: Simple tested-with:- , GHC == 9.10.1- , GHC == 9.6.5- , GHC == 9.8.2+ ghc ==9.6.7+ ghc ==9.8.4+ ghc ==9.10.2+ ghc ==9.12.2+ extra-doc-files:- ChangeLog.md- readme.org+ ChangeLog.md+ readme.org source-repository head- type: git- location: https://github.com/tonyday567/mealy+ type: git+ location: https://github.com/tonyday567/mealy common ghc-options-stanza- ghc-options:- -Wall- -Wcompat- -Widentities- -Wincomplete-record-updates- -Wincomplete-uni-patterns- -Wpartial-fields- -Wredundant-constraints+ ghc-options:+ -Wall+ -Wcompat+ -Widentities+ -Wincomplete-record-updates+ -Wincomplete-uni-patterns+ -Wpartial-fields+ -Wredundant-constraints -common ghc2021-stanza- default-language: GHC2021+common ghc2024-additions+ default-extensions:+ DataKinds+ DerivingStrategies+ DisambiguateRecordFields+ ExplicitNamespaces+ GADTs+ LambdaCase+ MonoLocalBinds+ RoleAnnotations +common ghc2024-stanza+ if impl(ghc >=9.10)+ default-language:+ GHC2024+ else+ import: ghc2024-additions+ default-language:+ GHC2021+ library- import: ghc-options-stanza- import: ghc2021-stanza- hs-source-dirs: src- build-depends:- , adjunctions >=4.0 && <4.5- , base >=4.14 && <5- , containers >=0.6 && <0.8- , mwc-probability >=2.3.1 && <2.4- , numhask >=0.11 && <0.13- , harpie >=0.1 && <0.2- , harpie-numhask >=0.1 && <0.2- , primitive >=0.7.2 && <0.10- , profunctors >=5.6.2 && <5.7- , tdigest >=0.2.1 && <0.4- , text >=1.2 && <2.2- , vector >=0.12.3 && <0.14- , vector-algorithms >=0.8.0 && <0.10- exposed-modules:- Data.Mealy- Data.Mealy.Quantiles- Data.Mealy.Simulate+ import: ghc-options-stanza+ import: ghc2024-stanza+ hs-source-dirs: src+ build-depends:+ adjunctions >=4.0 && <4.5,+ base >=4.14 && <5,+ containers >=0.6 && <0.9,+ harpie >=0.1 && <0.2,+ harpie-numhask >=0.1 && <0.2,+ mwc-probability >=2.3.1 && <2.4,+ numhask >=0.11 && <0.14,+ primitive >=0.7.2 && <0.10,+ profunctors >=5.6.2 && <5.7,+ tdigest >=0.2.1 && <0.4,+ text >=1.2 && <2.2,+ vector >=0.12.3 && <0.14,+ vector-algorithms >=0.8.0 && <0.10, + exposed-modules:+ Data.Mealy+ Data.Mealy.Quantiles+ Data.Mealy.Simulate+ test-suite doctests- import: ghc2021-stanza- main-is: doctests.hs- hs-source-dirs: test- build-depends:- , base >=4.14 && <5- , doctest-parallel >=0.3 && <0.4- , mealy- ghc-options: -threaded- type: exitcode-stdio-1.0+ import: ghc2024-stanza+ main-is: doctests.hs+ hs-source-dirs: test+ build-depends:+ base >=4.14 && <5,+ doctest-parallel >=0.3 && <0.5,+ mealy,++ ghc-options: -threaded+ type: exitcode-stdio-1.0++common ghc-options-exe-stanza+ ghc-options:+ -fforce-recomp+ -funbox-strict-fields+ -rtsopts+ -threaded+ -with-rtsopts=-N++executable mealy-perf+ import: ghc-options-exe-stanza+ import: ghc-options-stanza+ import: ghc2024-stanza+ main-is: mealy-perf.hs+ hs-source-dirs: test+ build-depends:+ base >=4.7 && <5,+ clock >=0.8 && <0.9,+ containers >=0.6 && <0.9,+ deepseq >=1.4.4 && <1.6,+ formatn >=0.2.1 && <0.4,+ harpie >=0.1 && <0.2,+ harpie-numhask >=0.1 && <0.2,+ mealy,+ mtl >=2.2.2 && <2.4,+ optics-core >=0.4 && <0.5,+ optparse-applicative >=0.17 && <0.20,+ perf >=0.14 && <0.15,+ tdigest >=0.2.1 && <0.4,+ text >=1.2 && <2.2,+ time >=1.10 && <1.15,++ ghc-options: -O2
readme.org view
@@ -1,6 +1,6 @@ #+TITLE: mealy -[[https://hackage.haskell.org/package/mealy][file:https://img.shields.io/hackage/v/mealy.svg]] [[https://github.com/tonyday567/mealy/actions?query=workflow%3Ahaskell-ci][file:https://github.com/tonyday567/mealy/workflows/haskell-ci/badge.svg]]+[[https://hackage.haskell.org/package/mealy][file:https://img.shields.io/hackage/v/mealy.svg]] [[https://github.com/tonyday567/mealy/actions/workflows/haskell-ci.yml][file:https://github.com/tonyday567/mealy/actions/workflows/haskell-ci.yml/badge.svg]] A 'Mealy' is a triple of functions
src/Data/Mealy.hs view
@@ -64,7 +64,6 @@ import Data.Sequence (Seq) import Data.Sequence qualified as Seq import Data.Text (Text)-import Data.Typeable (Typeable) import GHC.TypeLits import Harpie.Fixed qualified as F import Harpie.NumHask qualified as N@@ -100,7 +99,7 @@ -- >>> xsp <- rvsp g 10000 0.8 newtype MealyError = MealyError {mealyErrorMessage :: Text}- deriving (Show, Typeable)+ deriving (Show) instance Exception MealyError
src/Data/Mealy/Quantiles.hs view
@@ -7,6 +7,11 @@ quantiles, digitize, signalize,+ OnlineTDigest (..),+ emptyOnlineTDigest,+ onlineInsert,+ onlineCompress,+ onlineForceCompress, ) where
+ test/mealy-perf.hs view
@@ -0,0 +1,101 @@+{-# LANGUAGE OverloadedStrings #-}++-- | performance measurement+module Main where++import Control.Category (id)+import Control.Monad+import Data.List (intercalate)+import Data.Map.Strict (Map)+import Data.Maybe+import Data.Mealy+import Data.Mealy.Quantiles+import Data.Mealy.Simulate+import Data.TDigest hiding (median)+import Data.Text (Text)+import Options.Applicative+import Perf+import Prelude hiding (id)++data Run = RunStats | RunQuantiles [Double] deriving (Eq, Show)++data AppConfig = AppConfig+ { appReportOptions :: ReportOptions,+ appRun :: Run+ }+ deriving (Eq, Show)++parseRun :: Parser Run+parseRun =+ flag' RunStats (long "stats" <> help "run stats test")+ <|> flag' (RunQuantiles [0.1, 0.5, 0.9]) (long "quantiles" <> help "run quantiles test")+ <|> pure RunStats++parseAppConfig :: Parser AppConfig+parseAppConfig =+ AppConfig+ <$> parseReportOptions defaultReportOptions+ <*> parseRun++appInfo :: ParserInfo AppConfig+appInfo =+ info+ (parseAppConfig <**> helper)+ (fullDesc <> progDesc "mealy performance measurement")++main :: IO ()+main = do+ o <- execParser appInfo+ let repOptions = appReportOptions o+ let n = reportN repOptions+ let s = reportStatDType repOptions+ let mt = reportMeasureType repOptions+ let run = appRun o+ let l = reportLength repOptions+ gen <- create+ _ <- warmup 100+ case run of+ RunStats -> do+ xs <- rvs gen l+ reportMain ExampleSum repOptions (intercalate "-" [show run, show n, show l, show s, show mt]) (void . stats xs)+ RunQuantiles qs -> do+ xs <- rvs gen l+ reportMain ExampleSum repOptions (intercalate "-" [show run, show n, show l, show s, show mt]) (void . perfQuantiles xs qs)++reportRaw :: ReportOptions -> PerfT IO [[Double]] a -> IO (a, Map Text [[Double]])+reportRaw o t = do+ let !n = reportN o+ let c = reportClock o+ let mt = reportMeasureType o+ runPerfT (measureDs mt c n) t++stats :: (Semigroup t) => [Double] -> Int -> PerfT IO t [[Double]]+stats xs l = do+ r1 <- ffap "stats" (scan ((,) <$> ma 0.99 <*> std 0.99)) (take l xs)+ r2 <- ffap "ma" (scan (ma 0.99)) xs+ r3 <- ffap "std" (scan (std 0.99)) xs+ pure [fst <$> r1, snd <$> r1, r2, r3]++perfQuantiles :: (Semigroup t) => [Double] -> [Double] -> Int -> PerfT IO t [Int]+perfQuantiles qs xs l = do+ r1 <- ffap "digitize" (scan (digitize 0.99 qs)) (take l xs)+ r2 <- ffap "digitize'" (scan (digitize' 0.99 qs)) (take l xs)+ pure (r1 <> r2)++digitize' :: Double -> [Double] -> Mealy Double Int+digitize' r qs = M inject step' extract+ where+ step' (x, _) a = (onlineInsert a x, a)+ inject a = (onlineInsert a (emptyOnlineTDigest r), a)+ extract (x, l) = bucket' qs' l+ where+ qs' = fromMaybe (0 / 0) . (`quantile` t) <$> qs+ (OnlineTDigest t _ _) = onlineCompress x+ bucket' xs l' =+ fold (M id (+) id) $+ ( \x' ->+ if x' > l'+ then 0+ else 1+ )+ <$> xs