online 0.3.0.0 → 0.4.0.0
raw patch · 6 files changed
+43/−70 lines, 6 filesdep −numhask-preludedep −protolude
Dependencies removed: numhask-prelude, protolude
Files
- online.cabal +7/−24
- src/Online/Averages.hs +17/−20
- src/Online/Medians.hs +3/−5
- src/Online/Quantiles.hs +15/−12
- stack.yaml +0/−8
- test/test.hs +1/−1
online.cabal view
@@ -1,11 +1,6 @@--- This file has been generated from package.yaml by hpack version 0.28.2.------ see: https://github.com/sol/hpack------ hash: 23ad67040f06c24d3eb357c48f10a503d156cb1d8cf9ded5a9f749d497c3f937-+cabal-version: 2.0 name: online-version: 0.3.0.0+version: 0.4.0.0 synopsis: online statistics description: transformation of statistics to online algorithms category: statistics@@ -17,34 +12,26 @@ license: BSD3 license-file: LICENSE build-type: Simple-cabal-version: >= 1.10-extra-source-files:- stack.yaml source-repository head type: git location: https://github.com/tonyday567/online library+ exposed-modules:+ Online+ Online.Averages+ Online.Medians+ Online.Quantiles hs-source-dirs: src- default-extensions: NegativeLiterals NoImplicitPrelude OverloadedStrings UnicodeSyntax ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints build-depends: base >=4.7 && <5 , foldl- , numhask-prelude- , protolude , tdigest , vector , vector-algorithms- exposed-modules:- Online- Online.Averages- Online.Medians- Online.Quantiles- other-modules:- Paths_online default-language: Haskell2010 test-suite test@@ -52,12 +39,8 @@ main-is: test.hs hs-source-dirs: test- default-extensions: NegativeLiterals NoImplicitPrelude OverloadedStrings UnicodeSyntax build-depends: base >=4.7 && <5 , doctest- , protolude , tasty- other-modules:- Paths_online default-language: Haskell2010
src/Online/Averages.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-}-{-# LANGUAGE NoImplicitPrelude #-} -- | online statistics based on a moving average module Online.Averages@@ -21,7 +20,7 @@ import qualified Control.Foldl as L import Control.Foldl (Fold(..))-import NumHask.Prelude+import Prelude -- | Most common statistics are averages. newtype Averager a b = Averager@@ -37,18 +36,16 @@ mappend = (<>) -- | online takes a function and turns it into a `Control.Foldl.Fold` where the step is an incremental update of the (isomorphic) statistic.-online :: (Field b) => (a -> b) -> (b -> b) -> Fold a b+online :: (Fractional b) => (a -> b) -> (b -> b) -> Fold a b online f g = Fold step begin extract where- begin = Averager (zero, zero)- step (Averager (s, c)) a = Averager (g $ s + f a, g $ c + one)+ begin = Averager (0, 0)+ step (Averager (s, c)) a = Averager (g $ s + f a, g $ c + 1) extract (Averager (s, c)) = s / c {-# INLINABLE online #-} -- $setup ----- >>> :set -XNoImplicitPrelude--- >>> import NumHask.Prelude -- >>> import qualified Control.Foldl as L -- >>> let n = 100 -- >>> let r = 0.9@@ -60,23 +57,23 @@ -- >>> L.fold (ma 1) [0..100] -- 50.0 ----- >>> L.fold (ma 1e-12) [0..100] ≈ 100--- True+-- >>> L.fold (ma 1e-12) [0..100]+-- 99.999999999999 -- -- >>> L.fold (ma 0.9) [0..100] -- 91.00241448887785 ---ma :: (Field a) => a -> Fold a a-ma r = online identity (* r)+ma :: (Fractional a) => a -> Fold a a+ma r = online id (* r) {-# INLINABLE ma #-} -- | absolute average-absma :: (Field a, Signed a) => a -> Fold a a+absma :: (Fractional a) => a -> Fold a a absma r = online abs (* r) {-# INLINABLE absma #-} -- | average square-sqma :: (Field a) => a -> Fold a a+sqma :: (Fractional a) => a -> Fold a a sqma r = online (\x -> x * x) (* r) {-# INLINABLE sqma #-} @@ -95,20 +92,20 @@ -- -- >>> L.fold (std 0.99) [0..1000] -- 99.28328803164005-std :: (ExpField a) => a -> Fold a a-std r = (\s ss -> sqrt (ss - s ** (one+one))) <$> ma r <*> sqma r+std :: (Fractional a, Floating a) => a -> Fold a a+std r = (\s ss -> sqrt (ss - s ** 2)) <$> ma r <*> sqma r {-# INLINABLE std #-} -- | the covariance of a tuple -- given an underlying central tendency fold-cov :: (Field a) => Fold a a -> Fold (a, a) a+cov :: (Num a) => Fold a a -> Fold (a, a) a cov m = (\xy x' y' -> xy - x' * y') <$> L.premap (uncurry (*)) m <*> L.premap fst m <*> L.premap snd m {-# INLINABLE cov #-} -- | correlation of a tuple, specialised to Guassian-corrGauss :: (ExpField a) => a -> Fold (a, a) a+corrGauss :: (Floating a) => a -> Fold (a, a) a corrGauss r = (\cov' stdx stdy -> cov' / (stdx * stdy)) <$> cov (ma r) <*> L.premap fst (std r) <*>@@ -116,7 +113,7 @@ {-# INLINABLE corrGauss #-} -- | a generalised version of correlation of a tuple-corr :: (Field a) => Fold a a -> Fold a a -> Fold (a, a) a+corr :: (Floating a) => Fold a a -> Fold a a -> Fold (a, a) a corr central deviation = (\cov' stdx stdy -> cov' / (stdx * stdy)) <$> cov central <*> L.premap fst deviation <*>@@ -125,7 +122,7 @@ -- | the beta in a simple linear regression of a tuple -- given an underlying central tendency fold-beta :: (Field a) => Fold a a -> Fold (a, a) a+beta :: (Fractional a) => Fold a a -> Fold (a, a) a beta m = (\xy x' y' x2 -> (xy - x' * y') / (x2 - x' * x')) <$> L.premap (uncurry (*)) m <*> L.premap fst m <*>@@ -134,7 +131,7 @@ {-# INLINABLE beta #-} -- | the alpha of a tuple-alpha :: (Field a) => Fold a a -> Fold (a, a) a+alpha :: (Fractional a) => Fold a a -> Fold (a, a) a alpha m = (\y b x -> y - b * x) <$> L.premap fst m <*> beta m <*> L.premap snd m {-# INLINABLE alpha #-}
src/Online/Medians.hs view
@@ -16,7 +16,7 @@ import qualified Control.Foldl as L import Control.Foldl (Fold(..))-import Protolude+import Prelude -- | A rough Median. -- The average absolute value of the stat is used to callibrate estimate drift towards the median@@ -56,8 +56,6 @@ -- $setup ----- >>> :set -XNoImplicitPrelude--- >>> import NumHask.Prelude -- >>> import qualified Control.Foldl as L -- >>> let n = 100 -- >>> let inc = 0.1@@ -69,12 +67,12 @@ -- 93.92822312742108 -- maL1 :: (Ord a, Fractional a) => a -> a -> a -> Fold a a-maL1 i d r = onlineL1 i d identity (* r)+maL1 i d r = onlineL1 i d id (* r) {-# INLINABLE maL1 #-} -- | moving absolute deviation absmaL1 :: (Ord a, Fractional a) => a -> a -> a -> Fold a a-absmaL1 i d r = fst <$> onlineL1' i d identity (* r)+absmaL1 i d r = fst <$> onlineL1' i d id (* r) {-# INLINABLE absmaL1 #-} -- | covariance of a tuple
src/Online/Quantiles.hs view
@@ -20,7 +20,11 @@ import Data.TDigest.Postprocess (HistBin, histogram) import qualified Data.Vector.Algorithms.Heap as VHeap import qualified Data.Vector.Unboxed as VU-import NumHask.Prelude+import Prelude+import Control.Monad.ST (runST)+import Data.Maybe+import Data.Ord+import Data.Foldable -- | a raw non-online tdigest fold tDigest :: L.Fold Double (TDigest 25)@@ -28,7 +32,7 @@ where step x a = insert a x begin = tdigest ([] :: [Double]) :: TDigest 25- done = identity+ done = id -- | non-online version tDigestQuantiles :: [Double] -> L.Fold Double [Double]@@ -36,7 +40,7 @@ where step x a = 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 -- | non-online version tDigestHist :: L.Fold Double (Maybe (NonEmpty HistBin))@@ -61,7 +65,7 @@ where step x a = onlineInsert a x begin = emptyOnlineTDigest r- done x = fromMaybe nan . (`quantile` t) <$> qs+ done x = fromMaybe (0/0) . (`quantile` t) <$> qs where (OnlineTDigest t _ _) = onlineForceCompress x @@ -70,14 +74,14 @@ where step x a = onlineInsert a x begin = emptyOnlineTDigest r- done x = fromMaybe nan (quantile 0.5 t)+ done x = fromMaybe (0/0) (quantile 0.5 t) where (OnlineTDigest t _ _) = onlineForceCompress x onlineInsert' :: Double -> OnlineTDigest -> OnlineTDigest onlineInsert' x (OnlineTDigest td' n r) = OnlineTDigest- (insertCentroid (x, r ^^ (-(fromIntegral $ n + 1))) td')+ (insertCentroid (x, r ^^ (-(fromIntegral $ n + 1) :: Integer)) td') (n + 1) r @@ -98,8 +102,8 @@ onlineForceCompress (OnlineTDigest t n r) = OnlineTDigest t' 0 r where t' =- NumHask.Prelude.foldl' (flip insertCentroid) emptyTDigest $- (\(m, w) -> (m, w * (r ^^ fromIntegral n))) . fst <$> VU.toList centroids+ foldl' (flip insertCentroid) emptyTDigest $+ (\(m, w) -> (m, w * (r ^^ n))) . fst <$> VU.toList centroids -- Centroids are shuffled based on space centroids :: VU.Vector (Centroid, Double) centroids =@@ -107,17 +111,16 @@ v <- toMVector t -- sort by cumulative weight VHeap.sortBy (comparing snd) v- f <- VU.unsafeFreeze v- pure f+ VU.unsafeFreeze v onlineDigitize :: Double -> [Double] -> L.Fold Double Int onlineDigitize r qs = L.Fold step begin done where step (x, _) a = (onlineInsert a x, a)- begin = (emptyOnlineTDigest r, nan)+ begin = (emptyOnlineTDigest r, 0/0) done (x, l) = bucket' qs' l where- qs' = fromMaybe nan . (`quantile` t) <$> qs+ qs' = fromMaybe (0/0) . (`quantile` t) <$> qs (OnlineTDigest t _ _) = onlineForceCompress x bucket' xs l' = L.fold L.sum $
− stack.yaml
@@ -1,8 +0,0 @@-resolver: nightly-2018-06-02--packages:- - .--extra-deps: []--# allow-newer: true
test/test.hs view
@@ -2,7 +2,7 @@ module Main where -import Protolude+import Prelude import Test.Tasty (TestTree, testGroup, defaultMain) import Test.DocTest