mealy 0.4.3 → 0.4.4
raw patch · 6 files changed
+224/−111 lines, 6 filesdep ~adjunctionsdep ~basedep ~containers
Dependency ranges changed: adjunctions, base, containers, numhask-array, profunctors, tdigest, text
Files
- ChangeLog.md +4/−0
- LICENSE +30/−0
- mealy.cabal +106/−104
- readme.org +36/−0
- src/Data/Mealy.hs +41/−6
- src/Data/Mealy/Quantiles.hs +7/−1
+ ChangeLog.md view
@@ -0,0 +1,4 @@+0.4.4+===++- Added some common patterns
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2013, Tony Day++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 Tony Day 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.
mealy.cabal view
@@ -1,117 +1,119 @@ cabal-version: 3.0-name: mealy-version: 0.4.3-license: BSD-3-Clause-copyright: Tony Day (c) 2013 - 2022-maintainer: tonyday567@gmail.com-author: Tony Day-homepage: https://github.com/tonyday567/mealy#readme-bug-reports: https://github.com/tonyday567/mealy/issues-synopsis: Mealy machines for processing time-series and ordered data.+name: mealy+version: 0.4.4+license: BSD-3-Clause+license-file: LICENSE+copyright: Tony Day (c) 2013+category: algorithm+author: Tony Day+maintainer: tonyday567@gmail.com+homepage: https://github.com/tonyday567/mealy#readme+bug-reports: https://github.com/tonyday567/mealy/issues+synopsis: Mealy machines for processing time-series and ordered data. description:- @mealy@ provides support for computing statistics (such as an average or a standard deviation)- as current state. Usage is to supply a decay function representing the relative weights of recent values versus older ones, in the manner of exponentially-weighted averages. The library attempts to be polymorphic in the statistic which can be combined in applicative style.+ @mealy@ provides support for computing statistics (such as an average or a standard deviation) as current state. Usage is to supply a decay function representing the relative weights of recent values versus older ones, in the manner of exponentially-weighted averages. The library attempts to be polymorphic in the statistic which can be combined in applicative style. - == 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) -category: folding-build-type: Simple-tested-with: GHC == 8.10.7 || ==9.2.8 || ==9.4.5 || ==9.6.2+build-type: Simple+tested-with: GHC == 8.10.7 || ==9.2.8 || ==9.4.5 || ==9.6.2+extra-doc-files:+ 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+ common ghc2021-stanza- if impl(ghc >=9.2)- default-language:- GHC2021- if impl(ghc <9.2)- default-language:- Haskell2010- default-extensions:- BangPatterns- BinaryLiterals- ConstrainedClassMethods- ConstraintKinds- DeriveDataTypeable- DeriveFoldable- DeriveFunctor- DeriveGeneric- DeriveLift- DeriveTraversable- DoAndIfThenElse- EmptyCase- EmptyDataDecls- EmptyDataDeriving- ExistentialQuantification- ExplicitForAll- FlexibleContexts- FlexibleInstances- ForeignFunctionInterface- GADTSyntax- GeneralisedNewtypeDeriving- HexFloatLiterals- ImplicitPrelude- InstanceSigs- KindSignatures- MonomorphismRestriction- MultiParamTypeClasses- NamedFieldPuns- NamedWildCards- NumericUnderscores- PatternGuards- PolyKinds- PostfixOperators- RankNTypes- RelaxedPolyRec- ScopedTypeVariables- StandaloneDeriving- StarIsType- TraditionalRecordSyntax- TupleSections- TypeApplications- TypeOperators- TypeSynonymInstances- if impl(ghc <9.2) && impl(ghc >=8.10)- default-extensions:- ImportQualifiedPost- StandaloneKindSignatures+ if impl ( ghc >= 9.2 )+ default-language: GHC2021 -common ghc-options-stanza- ghc-options:- -Wall- -Wcompat- -Wincomplete-record-updates- -Wincomplete-uni-patterns- -Wredundant-constraints- -Widentities- -Wpartial-fields+ if impl ( ghc < 9.2 )+ default-language: Haskell2010+ default-extensions:+ BangPatterns+ BinaryLiterals+ ConstrainedClassMethods+ ConstraintKinds+ DeriveDataTypeable+ DeriveFoldable+ DeriveFunctor+ DeriveGeneric+ DeriveLift+ DeriveTraversable+ DoAndIfThenElse+ EmptyCase+ EmptyDataDecls+ EmptyDataDeriving+ ExistentialQuantification+ ExplicitForAll+ FlexibleContexts+ FlexibleInstances+ ForeignFunctionInterface+ GADTSyntax+ GeneralisedNewtypeDeriving+ HexFloatLiterals+ ImplicitPrelude+ InstanceSigs+ KindSignatures+ MonomorphismRestriction+ MultiParamTypeClasses+ NamedFieldPuns+ NamedWildCards+ NumericUnderscores+ PatternGuards+ PolyKinds+ PostfixOperators+ RankNTypes+ RelaxedPolyRec+ ScopedTypeVariables+ StandaloneDeriving+ StarIsType+ TraditionalRecordSyntax+ TupleSections+ TypeApplications+ TypeOperators+ TypeSynonymInstances -library- import: ghc2021-stanza- import: ghc-options-stanza- exposed-modules:- Data.Mealy- Data.Mealy.Quantiles- Data.Mealy.Simulate+ if impl ( ghc < 9.2 ) && impl ( ghc >= 8.10 )+ default-extensions:+ ImportQualifiedPost+ StandaloneKindSignatures - hs-source-dirs: src- build-depends:- , adjunctions ^>=4.4- , base >=4.12 && <5- , containers ^>=0.6.2- , mwc-probability ^>=2.3.1- , numhask >=0.10 && <0.12- , numhask-array >=0.10.1 && <0.12- , primitive >=0.7.2 && <0.9- , profunctors ^>=5.6.2- , tdigest >=0.2.1 && <4- , text >=1.2.4 && <2.1- , vector >=0.12.3 && <0.14- , vector-algorithms >=0.8.0 && <0.10+library+ import: ghc-options-stanza+ import: ghc2021-stanza+ hs-source-dirs: src+ build-depends:+ , adjunctions >=4.0 && <5+ , base >=4.7 && <5+ , containers >=0.6 && <0.7+ , mwc-probability ^>=2.3.1+ , numhask >=0.10 && <0.12+ , numhask-array >=0.10 && <0.12+ , primitive >=0.7.2 && <0.9+ , profunctors >=5.6.2 && <5.7+ , tdigest >=0.2.1 && <0.4+ , text >=1.2 && <2.1+ , vector >=0.12.3 && <0.14+ , vector-algorithms >=0.8.0 && <0.10+ exposed-modules:+ Data.Mealy+ Data.Mealy.Quantiles+ Data.Mealy.Simulate
+ readme.org view
@@ -0,0 +1,36 @@+#+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]]++A 'Mealy' is a triple of functions++- (a -> b) *inject*: Convert (initial) input into the (initial) state type.+- (b -> a -> b) *step*: Update state given prior state and (new) input.+- (c -> b) *extract*: Convert state to the output type.++A sum, for example, looks like ~M id (+) id~ where the first id is the initial injection and the second id is the covariant extraction.++This library provides support for computing statistics (such as an average or a standard deviation)+as current state within a mealy context.++* Usage++Usage is to supply a decay function representing the relative weights of recent values versus older ones, in the manner of exponentially-weighted averages. The library attempts to be polymorphic in the statistic which can be combined in applicative style.++#+begin_src haskell :results output+:set prompt "> "+import Prelude+import Data.Mealy+#+end_src++#+begin_src haskell :results output+fold ((,) <$> ma 0.9 <*> std 0.9) [1..100::Double]+#+end_src++#+RESULTS:+: (91.00265621044142,9.472822805289121)+++* Reference++[[https://stackoverflow.com/questions/27997155/finite-state-transducers-in-haskell][Finite State Transducers]]
src/Data/Mealy.hs view
@@ -40,6 +40,12 @@ delay1, delay, window,+ diff,+ gdiff,+ same,+ countM,+ sumM,+ listify, -- * median Medianer (..),@@ -53,6 +59,7 @@ import Data.Bifunctor import Data.Functor.Rep import Data.List (scanl')+import Data.Map qualified as Map import Data.Profunctor import Data.Sequence (Seq) import Data.Sequence qualified as Seq@@ -60,7 +67,7 @@ import Data.Typeable (Typeable) import GHC.TypeLits import NumHask.Array as F-import NumHask.Prelude hiding (L1, asum, fold, id, last, (.))+import NumHask.Prelude hiding (asum, diff, fold, id, last, (.)) -- $setup --@@ -94,11 +101,11 @@ instance Exception MealyError --- | A 'Mealy' is a triple of functions+-- | A 'Mealy' a b is a triple of functions ----- * (a -> b) __inject__ Convert an input into the state type.--- * (b -> a -> b) __step__ Update state given prior state and (new) input.--- * (c -> b) __extract__ Convert state to the output type.+-- * (a -> s) __inject__ Convert an input into the state type.+-- * (s -> a -> s) __step__ Update state given prior state and (new) input.+-- * (s -> b) __extract__ Convert state to the output type. -- -- By adopting this order, a Mealy sum looks like: --@@ -106,7 +113,7 @@ -- -- where the first id is the initial injection to a contravariant position, and the second id is the covariant extraction. ----- __inject__ kicks off state on the initial element of the Foldable, but is otherwise be independent of __step__.+-- __inject__ kicks off state on the initial element of the Foldable, but is otherwise independent of __step__. -- -- > scan (M i s e) (x : xs) = e <$> scanl' s (i x) xs data Mealy a b = forall c. Mealy (a -> c) (c -> a -> c) (c -> b)@@ -492,6 +499,34 @@ window :: Int -> Mealy a (Seq.Seq a) window n = M Seq.singleton (\xs x -> Seq.take n (x Seq.<| xs)) id {-# INLINEABLE window #-}++-- | binomial operator applied to last and this value+diff :: (a -> a -> b) -> Mealy a b+diff f = f <$> id <*> delay1 undefined++-- | generalised diff function.+gdiff :: (a -> b) -> (a -> a -> b) -> Mealy a b+gdiff d0 d = M (\a -> (d0 a, a)) (\(_, a') a -> (d a a', a)) fst++-- | Unchanged since last time.+same :: (Eq b) => (a -> b) -> Mealy a Bool+same b = M (\a -> (True, b a)) (\(s, x) a -> (s && b a == x, x)) fst++-- | Count observed values+countM :: (Ord a) => Mealy a (Map.Map a Int)+countM = M (`Map.singleton` 1) (\m k -> Map.insertWith (+) k 1 m) id++-- | Sum values of a key-value pair.+sumM :: (Ord a, Additive b) => Mealy (a, b) (Map.Map a b)+sumM = M (uncurry Map.singleton) (\m (k, v) -> Map.insertWith (+) k v m) id++-- | Convert a Mealy to a Mealy operating on lists.+listify :: Mealy a b -> Mealy [a] [b]+listify (M sExtract sStep sInject) = M extract step inject+ where+ extract = fmap sExtract+ step = zipWith sStep+ inject = fmap sInject -- | A rough Median. -- The average absolute value of the stat is used to callibrate estimate drift towards the median
src/Data/Mealy/Quantiles.hs view
@@ -6,6 +6,7 @@ ( median, quantiles, digitize,+ signalize, ) where @@ -88,7 +89,7 @@ VU.unsafeFreeze v -- | A mealy that computes the running quantile bucket. For example,--- in a scan, @digitize 0.9 [0,0.5,1]@ returns:+-- in a scan, @digitize 0.9 [0.5]@ returns: -- -- * 0 if the current value is less than the current mealy median. --@@ -110,3 +111,8 @@ else 1 ) <$> xs++-- | transform an input to a [0,1] signal, via digitalization.+signalize :: Double -> [Double] -> Mealy Double Double+signalize r qs' =+ (\x -> fromIntegral x / fromIntegral (length qs' + 1)) <$> digitize r qs'