foldl-statistics 0.1.4.6 → 0.1.5.0
raw patch · 4 files changed
+129/−83 lines, 4 filesdep +containersdep +hashabledep +unordered-containersdep ~basedep ~criteriondep ~foldlPVP ok
version bump matches the API change (PVP)
Dependencies added: containers, hashable, unordered-containers
Dependency ranges changed: base, criterion, foldl, foldl-statistics, profunctors, semigroups, statistics
API changes (from Hackage documentation)
+ Control.Foldl.Statistics: histogram :: Ord a => Fold a (Map a Int)
+ Control.Foldl.Statistics: histogram' :: (Hashable a, Eq a) => Fold a (HashMap a Int)
+ Control.Foldl.Statistics: ordersOfMagnitude :: Fold Double (Map Double Int)
Files
- CHANGELOG.md +3/−0
- foldl-statistics.cabal +69/−77
- src/Control/Foldl/Statistics.hs +41/−2
- test/Spec.hs +16/−4
CHANGELOG.md view
@@ -1,3 +1,6 @@+# 0.1.5.0+- Added `histogram`, `histogram'` and `ordersOfMagnitude`.+ # 0.1.4.6 - Relax bounds on tasty-quickcheck
foldl-statistics.cabal view
@@ -1,82 +1,74 @@-name: foldl-statistics-version: 0.1.4.6-cabal-version: >=1.10-build-type: Simple-license: BSD3-license-file: LICENSE-copyright: 2016 Data61 (CSIRO)-maintainer: Alex.Mason@data61.csiro.au-homepage: http://github.com/Data61/foldl-statistics#readme-synopsis: Statistical functions from the statistics package implemented as- Folds.-description:- The use of this package allows statistics to be computed using at most two- passes over the input data, one to compute a mean and one to compute a further- statistic such as variance and /n/th central moments. All algorithms are the- obvious implementation of Bryan O\'Sullivan\'s- <https://hackage.haskell.org/package/statistics statistics> package imeplemented- as `Fold's from the- <https://hackage.haskell.org/package/foldl foldl> package.-category: Math, Statistics-author: Alex Mason-extra-source-files:- CHANGELOG.md- README.md--source-repository head- type: git- location: https://github.com/Data61/foldl-statistics+name: foldl-statistics+version: 0.1.5.0+synopsis: Statistical functions from the statistics package implemented as+ Folds.+description: The use of this package allows statistics to be computed using at most two+ passes over the input data, one to compute a mean and one to compute a further+ statistic such as variance and /n/th central moments. All algorithms are the+ obvious implementation of Bryan O\'Sullivan\'s+ <https://hackage.haskell.org/package/statistics statistics> package imeplemented+ as `Fold's from the+ <https://hackage.haskell.org/package/foldl foldl> package.+homepage: http://github.com/Data61/foldl-statistics#readme+license: BSD3+license-file: LICENSE+author: Alex Mason+maintainer: Alex.Mason@data61.csiro.au+copyright: 2016 Data61 (CSIRO)+category: Math, Statistics+build-type: Simple+extra-source-files: CHANGELOG.md, README.md+cabal-version: >=1.10+tested-with: GHC == 7.8.4, GHC == 7.10.2, GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.* library- - if impl(ghc <8.0)- build-depends:- semigroups >=0.18 && <1.0- exposed-modules:- Control.Foldl.Statistics- build-depends:- base >=4.7 && <5,- foldl >=1.1 && <1.4,- math-functions >=0.1 && <0.3,- profunctors ==5.2.*- default-language: Haskell2010- hs-source-dirs: src+ hs-source-dirs: src+ exposed-modules: Control.Foldl.Statistics+ default-language: Haskell2010+ build-depends: base >= 4.7 && < 5+ , foldl >= 1.1 && < 1.4+ , math-functions >= 0.1 && < 0.3+ , profunctors >= 5.2 && < 5.3+ , containers >= 0.1.0.0 && < 0.6+ , unordered-containers >= 0.1.0.0 && < 0.3+ , hashable >=1.0.1.1 && < 1.3+ if impl(ghc < 8.0)+ build-depends: semigroups >= 0.18 && < 1.0 + test-suite foldl-statistics-test- - if impl(ghc <8.0)- build-depends:- semigroups >=0.18.2 && <0.19- type: exitcode-stdio-1.0- main-is: Spec.hs- build-depends:- base >=4.7 && <5.0,- foldl-statistics >=0.1.4.6 && <0.2,- foldl >=1.2.5 && <1.3,- statistics >=0.13 && <0.15,- tasty ==0.11.*,- tasty-quickcheck >=0.8 && <0.10,- vector >=0.11 && <0.13,- quickcheck-instances ==0.3.*,- profunctors ==5.2.*- default-language: Haskell2010- hs-source-dirs: test- ghc-options: -threaded -rtsopts -with-rtsopts=-N+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Spec.hs+ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ default-language: Haskell2010+ build-depends: base+ , foldl-statistics+ , foldl+ , statistics >= 0.13 && < 0.15+ , tasty >= 0.11 && < 0.12+ , tasty-quickcheck >= 0.8 && < 0.10+ , vector >= 0.11 && < 0.13+ , quickcheck-instances >= 0.3 && < 0.4+ , profunctors+ if impl(ghc < 8.0)+ build-depends: semigroups -benchmark bench-folds- - if impl(ghc <8.0)- build-depends:- semigroups >=0.18.2 && <0.19- type: exitcode-stdio-1.0- main-is: Main.hs- build-depends:- base >=4.9.1.0 && <4.10,- foldl-statistics >=0.1.4.6 && <0.2,- criterion ==1.1.*,- vector >=0.10 && <1.0,- statistics >=0.13.3.0 && <0.14,- mwc-random ==0.13.*,- foldl >=1.2.5 && <1.3- default-language: Haskell2010- hs-source-dirs: bench+Benchmark bench-folds+ type: exitcode-stdio-1.0+ hs-source-dirs: bench+ main-is: Main.hs+ default-language: Haskell2010+ build-depends: base+ , foldl-statistics+ , foldl+ , statistics >= 0.13 && < 0.15+ , criterion >= 1.1 && < 1.3+ , vector >= 0.10 && < 1.0+ , mwc-random >= 0.13 && < 0.14+ if impl(ghc < 8.0)+ build-depends: semigroups++source-repository head+ type: git+ location: https://github.com/Data61/foldl-statistics
src/Control/Foldl/Statistics.hs view
@@ -1,10 +1,11 @@ {-# LANGUAGE CPP #-}+ -- | -- Module : Control.Foldl.Statistics--- Copyright : (c) 2011 Bryan O'Sullivan, 2016 National ICT Australia+-- Copyright : (c) 2011 Bryan O'Sullivan, 2016 National ICT Australia, 2018 CSIRO -- License : BSD3 ----- Maintainer : alex.mason@nicta.com.au+-- Maintainer : Alex.Mason@data61.csiro.au -- Stability : experimental -- Portability : portable --@@ -15,6 +16,9 @@ -- * Descriptive functions range , sum'+ , histogram+ , histogram'+ , ordersOfMagnitude -- * Statistics of location , mean@@ -82,6 +86,10 @@ import Control.Applicative #endif +import Data.Hashable (Hashable)+import qualified Data.HashMap.Strict as Hash+import qualified Data.Map.Strict as Map+ import Numeric.Sum (KBNSum, add, kbn, zero) data T = T {-# UNPACK #-}!Double {-# UNPACK #-}!Int@@ -120,6 +128,37 @@ range = (\(Just lo) (Just hi) -> hi - lo) <$> F.minimum <*> F.maximum++-- | Create a histogram of each value of type a. Useful for folding over+-- categorical values, for example, a CSV where you have a data type for a+-- selection of categories.+--+-- It should not be used for continuous values which would lead to a high number+-- of keys. One way to avoid this is to use the `Profunctor` instance for `Fold`+-- to break your values into categories. For an example of doing this, see+-- `ordersOfMagnitude`.+histogram :: Ord a => Fold a (Map.Map a Int)+histogram = Fold step Map.empty id where+ step m a = Map.insertWith (+) a 1 m++-- | Like `histogram`, but for use when hashmaps would be more efficient for the+-- particular type @a@.+histogram' :: (Hashable a, Eq a) => Fold a (Hash.HashMap a Int)+histogram' = Fold step Hash.empty id where+ step m a = Hash.insertWith (+) a 1 m++-- | Provides a histogram of the orders of magnitude of the values in a series.+-- Negative values are placed in the @0.0@ category due to the behaviour of+-- `logBase`. it may be useful to use @lmap abs@ on this Fold to get a histogram+-- of the absolute magnitudes.++-- TODO: logBase 10 1000000 /= 6 but 5, fix this+ordersOfMagnitude :: Fold Double (Map.Map Double Int)+ordersOfMagnitude =+ dimap+ ((floor :: Double -> Int) . logBase 10)+ (Map.mapKeysMonotonic (10^^))+ histogram -- | Arithmetic mean. This uses Kahan-Babuška-Neumaier -- summation, so is more accurate than 'welfordMean' unless the input
test/Spec.hs view
@@ -50,7 +50,7 @@ <*> kurtosis m precision :: Double-precision = 0.0000000001+precision = 10e-9 cmpLMVSK :: Double -> LMVSK -> LMVSK -> Bool cmpLMVSK prec a b = let@@ -61,6 +61,16 @@ && t lmvskSkewness && ((==) `on` lmvskCount) a b +diffLMVSK :: LMVSK -> LMVSK -> LMVSK+diffLMVSK a b = LMVSK+ (t lmvskCount)+ (t lmvskMean)+ (t lmvskVariance)+ (t lmvskSkewness)+ (t lmvskKurtosis)+ where t f = f a - f b++ main :: IO () main = defaultMain $ testGroup "Results match Statistics.Sample"@@ -94,12 +104,14 @@ m = F.fold mean $ U.toList vec fast = F.fold fastLMVSK $ U.toList vec reference = F.fold (testLMVSK m) $ U.toList vec- in cmpLMVSK precision fast reference+ in QC.counterexample (unlines ["",show fast,show reference, "Diff:", show (diffLMVSK fast reference)]) $+ cmpLMVSK precision fast reference , QC.testProperty "LMVSKSemigroup" $ \v1 v2 -> U.length v1 > 2 && U.length v2 > 2 && U.sum (mappend v1 v1) /= U.product (mappend v1 v1) ==> let sep = getLMVSK $ F.fold foldLMVSKState (U.toList v1) <> F.fold foldLMVSKState (U.toList v2) tog = F.fold fastLMVSK (U.toList v1 ++ U.toList v2)- in cmpLMVSK precision sep tog+ in QC.counterexample (unlines ["",show sep,show tog, "Diff:", show (diffLMVSK sep tog)])+ $ cmpLMVSK precision sep tog || isNaN (lmvskKurtosis sep) || isNaN (lmvskKurtosis tog) ]@@ -191,4 +203,4 @@ withinPCT :: Double -> Double -> Double -> Bool-withinPCT pct a b = abs (a - b) * 100 / (min `on` abs) a b < pct+withinPCT pct a b = abs ((a - b) * 100 / (min `on` abs) a b) < pct