packages feed

random-variates 0.1.0.0 → 0.1.1.0

raw patch · 21 files changed

+848/−367 lines, 21 filesdep +HUnitdep +directorydep +erfdep ~basedep ~containersPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: HUnit, directory, erf, mtl, random-variates

Dependency ranges changed: base, containers

API changes (from Hackage documentation)

- Stochastic.Distribution: class ContinuousDistribution g where randDoubles n g0 = statefully (randDouble) n g0
- Stochastic.Distribution: class DiscreteDistribution g where randInt g = randIntIn (0, maxBound :: Int) g randInts n g0 = statefully (randInt) n g0 randIntIn (a, b) g0 = ((ceiling (toDbl (b - a + 1) * d)) + (a - 1), g1) where (d, g1) = randDouble g0
- Stochastic.Distribution: randDouble :: ContinuousDistribution g => g -> (Double, g)
- Stochastic.Distribution: randDoubles :: ContinuousDistribution g => Int -> g -> ([Double], g)
- Stochastic.Distribution: randInt :: DiscreteDistribution g => g -> (Int, g)
- Stochastic.Distribution: randIntIn :: DiscreteDistribution g => (Int, Int) -> g -> (Int, g)
- Stochastic.Distribution: randInts :: DiscreteDistribution g => Int -> g -> ([Int], g)
- Stochastic.Distributions: Distributions :: (Int -> Uniform) -> (Int -> Double -> Exponential) -> (Int -> Double -> Double -> Normal) -> (Int -> Int -> Double -> ZipF) -> (Int -> Double -> Geometric) -> (Int -> Double -> Poisson) -> (Int -> Double -> Bernoulli) -> (Int -> Double -> Int -> Binomial) -> Distributions
- Stochastic.Distributions: [mkBernoulli] :: Distributions -> Int -> Double -> Bernoulli
- Stochastic.Distributions: [mkBinomial] :: Distributions -> Int -> Double -> Int -> Binomial
- Stochastic.Distributions: [mkExp] :: Distributions -> Int -> Double -> Exponential
- Stochastic.Distributions: [mkGeometric] :: Distributions -> Int -> Double -> Geometric
- Stochastic.Distributions: [mkNormal] :: Distributions -> Int -> Double -> Double -> Normal
- Stochastic.Distributions: [mkPoisson] :: Distributions -> Int -> Double -> Poisson
- Stochastic.Distributions: [mkUniform] :: Distributions -> Int -> Uniform
- Stochastic.Distributions: [mkZipF] :: Distributions -> Int -> Int -> Double -> ZipF
- Stochastic.Distributions: class ContinuousDistribution g where randDoubles n g0 = statefully (randDouble) n g0
- Stochastic.Distributions: class DiscreteDistribution g where randInt g = randIntIn (0, maxBound :: Int) g randInts n g0 = statefully (randInt) n g0 randIntIn (a, b) g0 = ((ceiling (toDbl (b - a + 1) * d)) + (a - 1), g1) where (d, g1) = randDouble g0
- Stochastic.Distributions: data Distributions
- Stochastic.Distributions: liftC :: (ContinuousDistribution g) => (Double -> a) -> (g -> (a, g))
- Stochastic.Distributions: liftCN :: (ContinuousDistribution g) => Int -> ([Double] -> a) -> (g -> (a, g))
- Stochastic.Distributions: liftD :: (DiscreteDistribution g) => (Int, Int) -> (Int -> a) -> (g -> (a, g))
- Stochastic.Distributions: liftDN :: (DiscreteDistribution g) => [(Int, Int)] -> ([Int] -> a) -> (g -> (a, g))
- Stochastic.Distributions: mkDistributions :: (Int -> Uniform) -> Distributions
- Stochastic.Distributions: randDouble :: ContinuousDistribution g => g -> (Double, g)
- Stochastic.Distributions: randDoubles :: ContinuousDistribution g => Int -> g -> ([Double], g)
- Stochastic.Distributions: randInt :: DiscreteDistribution g => g -> (Int, g)
- Stochastic.Distributions: randIntIn :: DiscreteDistribution g => (Int, Int) -> g -> (Int, g)
- Stochastic.Distributions: randInts :: DiscreteDistribution g => Int -> g -> ([Int], g)
- Stochastic.Distributions: stdDistributions :: Distributions
- Stochastic.Uniform: Uniform :: (Double, Uniform) -> Uniform
- Stochastic.Uniform: [rDouble] :: Uniform -> (Double, Uniform)
- Stochastic.Uniform: data Uniform
- Stochastic.Uniform: instance Stochastic.Distribution.ContinuousDistribution Stochastic.Uniform.Uniform
- Stochastic.Uniform: stdUniform :: Int -> Uniform
+ Stochastic.Analysis: chiSquaredTest :: (ContinuousDistribution g) => g -> Empirical -> [Double] -> Double
+ Stochastic.Analysis: discreteChiSquaredTest :: (DiscreteDistribution g) => g -> Empirical -> [Int] -> Double
+ Stochastic.Distribution.Continuous: cdf :: ContinuousDistribution g => g -> Double -> Double
+ Stochastic.Distribution.Continuous: cdf' :: ContinuousDistribution g => g -> Double -> Double
+ Stochastic.Distribution.Continuous: class ContinuousDistribution g where rands n g0 = statefully (rand) n g0 pdf g a b = (cdf g b) - (cdf g a)
+ Stochastic.Distribution.Continuous: degreesOfFreedom :: ContinuousDistribution g => g -> Int
+ Stochastic.Distribution.Continuous: pdf :: ContinuousDistribution g => g -> Double -> Double -> Double
+ Stochastic.Distribution.Continuous: rand :: ContinuousDistribution g => g -> (Double, g)
+ Stochastic.Distribution.Continuous: rands :: ContinuousDistribution g => Int -> g -> ([Double], g)
+ Stochastic.Distribution.Discrete: cdf :: DiscreteDistribution g => g -> Int -> Double
+ Stochastic.Distribution.Discrete: cdf' :: DiscreteDistribution g => g -> Double -> Int
+ Stochastic.Distribution.Discrete: class DiscreteDistribution g where rands n g0 = statefully (rand) n g0
+ Stochastic.Distribution.Discrete: pmf :: DiscreteDistribution g => g -> Int -> Double
+ Stochastic.Distribution.Discrete: rand :: DiscreteDistribution g => g -> (Int, g)
+ Stochastic.Distribution.Discrete: rands :: DiscreteDistribution g => Int -> g -> ([Int], g)
+ Stochastic.Distributions: Empirical :: Int -> (Double -> Double) -> (Double -> Double) -> Empirical
+ Stochastic.Distributions: [cdf'] :: Empirical -> Double -> Double
+ Stochastic.Distributions: [cdf] :: Empirical -> Double -> Double
+ Stochastic.Distributions: [degreesOfFreedom] :: Empirical -> Int
+ Stochastic.Distributions: data Empirical
+ Stochastic.Distributions: data UniformBase
+ Stochastic.Distributions: mkEmpirical :: [Double] -> Empirical
+ Stochastic.Distributions: stdBase :: Int -> UniformBase
+ Stochastic.Distributions.Continuous: ChiSquared :: Int -> UniformBase -> Dist
+ Stochastic.Distributions.Continuous: Empirical :: Empirical -> UniformBase -> Dist
+ Stochastic.Distributions.Continuous: Exponential :: Double -> UniformBase -> Dist
+ Stochastic.Distributions.Continuous: Normal :: Double -> Double -> (Maybe Double) -> UniformBase -> Dist
+ Stochastic.Distributions.Continuous: Uniform :: UniformBase -> Dist
+ Stochastic.Distributions.Continuous: cdf :: ContinuousDistribution g => g -> Double -> Double
+ Stochastic.Distributions.Continuous: cdf' :: ContinuousDistribution g => g -> Double -> Double
+ Stochastic.Distributions.Continuous: class ContinuousDistribution g where rands n g0 = statefully (rand) n g0 pdf g a b = (cdf g b) - (cdf g a)
+ Stochastic.Distributions.Continuous: data Dist
+ Stochastic.Distributions.Continuous: degreesOfFreedom :: ContinuousDistribution g => g -> Int
+ Stochastic.Distributions.Continuous: instance Stochastic.Distribution.Continuous.ContinuousDistribution Stochastic.Distributions.Continuous.Dist
+ Stochastic.Distributions.Continuous: instance Stochastic.Distribution.Continuous.ContinuousDistribution Stochastic.Distributions.UniformBase
+ Stochastic.Distributions.Continuous: instance Stochastic.Generator.Generator Stochastic.Distributions.Continuous.Dist
+ Stochastic.Distributions.Continuous: instance Stochastic.Generator.Generator Stochastic.Distributions.UniformBase
+ Stochastic.Distributions.Continuous: mkEmpirical :: UniformBase -> [Double] -> Dist
+ Stochastic.Distributions.Continuous: mkExp :: UniformBase -> Double -> Dist
+ Stochastic.Distributions.Continuous: mkNormal :: UniformBase -> Double -> Double -> Dist
+ Stochastic.Distributions.Continuous: mkUniform :: UniformBase -> Dist
+ Stochastic.Distributions.Continuous: pdf :: ContinuousDistribution g => g -> Double -> Double -> Double
+ Stochastic.Distributions.Continuous: rand :: ContinuousDistribution g => g -> (Double, g)
+ Stochastic.Distributions.Continuous: rands :: ContinuousDistribution g => Int -> g -> ([Double], g)
+ Stochastic.Distributions.Discrete: Bernoulli :: Double -> UniformBase -> Dist
+ Stochastic.Distributions.Discrete: Binomial :: Int -> Double -> DiscreteCache -> UniformBase -> Dist
+ Stochastic.Distributions.Discrete: Geometric :: Double -> UniformBase -> Dist
+ Stochastic.Distributions.Discrete: Poisson :: Dist -> Dist
+ Stochastic.Distributions.Discrete: Uniform :: Int -> Int -> UniformBase -> Dist
+ Stochastic.Distributions.Discrete: ZipF :: Int -> Double -> DiscreteCache -> UniformBase -> Dist
+ Stochastic.Distributions.Discrete: cdf :: DiscreteDistribution g => g -> Int -> Double
+ Stochastic.Distributions.Discrete: cdf' :: DiscreteDistribution g => g -> Double -> Int
+ Stochastic.Distributions.Discrete: class DiscreteDistribution g where rands n g0 = statefully (rand) n g0
+ Stochastic.Distributions.Discrete: data Dist
+ Stochastic.Distributions.Discrete: instance Stochastic.Distribution.Discrete.DiscreteDistribution Stochastic.Distributions.Discrete.Dist
+ Stochastic.Distributions.Discrete: instance Stochastic.Generator.Generator Stochastic.Distributions.Discrete.Dist
+ Stochastic.Distributions.Discrete: mkBernoulli :: UniformBase -> Double -> Dist
+ Stochastic.Distributions.Discrete: mkBinomial :: UniformBase -> Double -> Int -> Dist
+ Stochastic.Distributions.Discrete: mkGeometric :: UniformBase -> Double -> Dist
+ Stochastic.Distributions.Discrete: mkPoisson :: UniformBase -> Double -> Dist
+ Stochastic.Distributions.Discrete: mkZipF :: UniformBase -> Int -> Double -> Dist
+ Stochastic.Distributions.Discrete: pmf :: DiscreteDistribution g => g -> Int -> Double
+ Stochastic.Distributions.Discrete: rand :: DiscreteDistribution g => g -> (Int, g)
+ Stochastic.Distributions.Discrete: rands :: DiscreteDistribution g => Int -> g -> ([Int], g)
+ Stochastic.Generator: class Generator g where type family From g nextN 0 = state $ \ g0 -> ([], g0) nextN n = do { x <- nextG; xs <- nextN (n - 1); return (x : xs) }
+ Stochastic.Generator: foldWhile :: Generator g => (From g -> a -> a) -> a -> (a -> Bool) -> State g [From g]
+ Stochastic.Generator: instance Stochastic.Generator.Generator [a]
+ Stochastic.Generator: nextG :: Generator g => State g (From g)
+ Stochastic.Generator: nextN :: Generator g => Int -> State g [(From g)]
+ Stochastic.Generator: while :: Generator g => ((From g) -> Bool) -> State g [From g]
+ Stochastic.Tools: Datagram :: Double -> Double -> Int -> Double -> Double -> Double -> Datagram
+ Stochastic.Tools: [cum_frequence] :: Datagram -> Double
+ Stochastic.Tools: [frequency] :: Datagram -> Int
+ Stochastic.Tools: [lower_bound] :: Datagram -> Double
+ Stochastic.Tools: [rel_frequence] :: Datagram -> Double
+ Stochastic.Tools: [slope] :: Datagram -> Double
+ Stochastic.Tools: [upper_bound] :: Datagram -> Double
+ Stochastic.Tools: accMap :: (b -> a -> b) -> (a -> b) -> [a] -> [b]
+ Stochastic.Tools: biFold :: (a -> a -> b) -> [a] -> [b]
+ Stochastic.Tools: bin :: (Double -> Double) -> [Double] -> [(Double, Int)]
+ Stochastic.Tools: comb :: Int -> Int -> Double
+ Stochastic.Tools: data Datagram
+ Stochastic.Tools: datagramFromRaw :: Int -> Double -> [(Double, Int)] -> [Datagram]
+ Stochastic.Tools: dependentMap :: (a -> a -> b) -> (a -> b) -> [a] -> [b]
+ Stochastic.Tools: estimate_lower_gamma :: Double -> Double -> Double -> Double
+ Stochastic.Tools: fIHistogram :: [Double] -> Histogram
+ Stochastic.Tools: fac :: Int -> Integer
+ Stochastic.Tools: factorial :: [Integer]
+ Stochastic.Tools: fib :: Int -> Integer
+ Stochastic.Tools: fibinacci :: [Integer]
+ Stochastic.Tools: gamma :: Double -> Double
+ Stochastic.Tools: group :: (Ord a) => [a] -> [(a, Int)]
+ Stochastic.Tools: groupSeq :: (Eq a) => [a] -> [(a, Int)]
+ Stochastic.Tools: harmonics :: Double -> [Double]
+ Stochastic.Tools: headOrElse :: a -> [a] -> a
+ Stochastic.Tools: histogram :: Double -> [Double] -> [Int]
+ Stochastic.Tools: instance GHC.Classes.Eq Stochastic.Tools.Datagram
+ Stochastic.Tools: instance GHC.Show.Show Stochastic.Tools.Datagram
+ Stochastic.Tools: lowerOf :: Double -> Double -> Double
+ Stochastic.Tools: lower_incomplete_gamma :: Double -> Double -> Double
+ Stochastic.Tools: mapTuple :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)
+ Stochastic.Tools: maxf :: Ord b => [b] -> b
+ Stochastic.Tools: maybeHead :: [a] -> Maybe a
+ Stochastic.Tools: minf :: Ord b => [b] -> b
+ Stochastic.Tools: statefully :: (g -> (a, g)) -> Int -> g -> ([a], g)
+ Stochastic.Tools: statefullyTakeWhile :: (g -> (a, g)) -> ([a] -> Bool) -> g -> ([a], g)
+ Stochastic.Tools: stirlingsApprox :: (Floating r, Ord r) => r -> r
+ Stochastic.Tools: type Histogram = [Datagram]

Files

random-variates.cabal view
@@ -2,9 +2,9 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                random-variates-version:             0.1.0.0+version:             0.1.1.0 synopsis:            "Uniform RNG => Non-Uniform RNGs"-description:         "Collection of transforms uniform random number generators (RNGs) into any of a dozen common RNGs. Each presenting several common interfaces"   +description:         "Collection of transforms uniform random number generators (RNGs) into any of a dozen common RNGs. Each presenting several common interfaces. Additionally Empirical distributions can be sampled from and tested (chi-squared) against theoretical distributions."    license:             MIT license-file:        LICENSE author:              Keynan James Pratt <keynan.pratt@gmail.com>@@ -21,23 +21,43 @@   location:            git@bitbucket.org:kpratt/random-variate.git      library-  exposed-modules:     Stochastic.Distribution-                       Stochastic.Distributions-                       Stochastic.Uniform+  exposed-modules:+                  Stochastic.Generator+                  Stochastic.Distribution.Continuous+                  Stochastic.Distribution.Discrete+                  Stochastic.Distributions+                  Stochastic.Distributions.Continuous+                  Stochastic.Distributions.Discrete+                  Stochastic.Analysis+                  Stochastic.Tools -  other-modules:       Stochastic.Bernoulli-                       Stochastic.Binomial-                       Stochastic.Exponential-                       Stochastic.Geometric-                       Stochastic.Normal-                       Stochastic.Poisson-                       Stochastic.ZipF-                       Helpers+  other-modules:    build-depends:       -                       base >=4.6 && <5.0-                       , reinterpret-cast >= 0.1.0-                       , containers >= 0.5.0.0+                         base >=4.6 && <5.0+                       , containers >= 0.5.7.0                        , lens >=4.13                        , random >=1.1+                       , reinterpret-cast >= 0.1.0+                       , mtl >= 2.2+                       , erf >= 2.0   hs-source-dirs:      src   default-language:    Haskell2010++Test-Suite vis+  type:                exitcode-stdio-1.0+  main-is:             tests/vis.hs+  build-depends:       base+                     , directory       >= 1.2.0.1+                     , random-variates >=0.1+  default-language:    Haskell2010+++Test-Suite units+  type:                exitcode-stdio-1.0+  main-is:             tests/unit.hs+  build-depends:       HUnit >= 1.3+                     , base+                     , random-variates >=0.1+  default-language:    Haskell2010++  
− src/Helpers.hs
@@ -1,56 +0,0 @@-module Helpers(maybeHead,-               headOrElse,-               statefully,-               mapTuple,-               statefullyTakeWhile,-               histogram) where--import Data.Maybe-import qualified Data.Map as Map--maybeHead :: [a] -> Maybe a-maybeHead []     = Nothing-maybeHead (x:xs) = Just x--headOrElse :: a -> [a] -> a-headOrElse d ls = fromMaybe d (maybeHead ls)--statefully :: (g -> (a, g)) -> Int -> g -> ([a], g)-statefully f n g0 = case n of-    0 -> ([], g0)-    x -> (r:rest, g2)-      where-        (r, g1) = f g0-        (rest, g2) = statefully f (n-1) g1--statefullyTakeWhile :: (g -> (a, g)) ->-                       ([a] -> Bool) ->-                       g ->-                       ([a], g)-statefullyTakeWhile f p g0 = r ([], g0)-  where-    r (list, g1)-      | p list    = (list, g1)-      | otherwise = mapTuple (\l -> l:list) (id) (f g1)---mapTuple :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)    -mapTuple f g (x, y) = (f x, g y)--histogram :: Double -> [Double] -> [Int]-histogram precision ls = map lookup0 [0..limit]-  where-    limit = truncate $ (1.0 / precision)-    divs = map (\x -> x / precision) ls-    ints = map (truncate) divs-    m   = foldl-          (\b a ->-            Map.insert a ((fromMaybe 0 (Map.lookup a b))+1) b)-          Map.empty-          ints-    lookup0 = (\x -> fromMaybe 0 $ Map.lookup x m)-    -toDbl = fromInteger . toInteger---
+ src/Stochastic/Analysis.hs view
@@ -0,0 +1,58 @@+module Stochastic.Analysis(chiSquaredTest, discreteChiSquaredTest) where++import qualified Stochastic.Distributions.Continuous as C+import qualified Stochastic.Distributions.Discrete as D++import Data.List(sort)+import Stochastic.Distributions+import Stochastic.Tools++chiCritD :: (C.ContinuousDistribution g)+            => g+            -> Empirical+            -> Double+            -> Double+chiCritD theory emp =+  chiCrit (degreesOfFreedom emp) (C.degreesOfFreedom theory)++-- k = number of intervals in the empirical histogram+-- s = number of parameters to the theoretical distribution+chiCrit :: Int -> Int -> Double -> Double+chiCrit k s alpha = C.cdf' chi (1-alpha)+  where+    df = k - s - 1+    chi = C.ChiSquared df (stdBase 42)++-- empirical distributions should be+-- given as the second argument+chiSquaredTest :: (C.ContinuousDistribution g)+                  => g+                  -> Empirical+                  -> [Double]+                  -> Double+chiSquaredTest c d sampleAt = if (isNaN final) then (error $ "frog") else final+  where+    final = sum $ fmap f sampleAt+    f x = let o =  cdf' d $ C.cdf c x in+           let e = x in+           let ret = ((e-o)**2) / e in+           if (isNaN ret)+           then error $ (show e) ++ " " ++ (show o) ++ " " ++ (show ret) ++ " " ++ (show (0/0))+           else ret+++discreteChiSquaredTest :: (D.DiscreteDistribution g)+                          => g+                          -> Empirical+                          -> [Int]+                          -> Double+discreteChiSquaredTest c d sampleAt = sum $ fmap f sampleAt+  where+    f :: Int -> Double+    f x = let e = D.cdf' c $ cdf d $ toDbl x in+           let o = x in+           toDbl ((e-o)^2) / toDbl e+    toDbl = fromInteger . toInteger+++
− src/Stochastic/Bernoulli.hs
@@ -1,20 +0,0 @@-module Stochastic.Bernoulli(Bernoulli, mkBernoulli) where--import Stochastic.Distribution-import Stochastic.Uniform-import Helpers--data Bernoulli = Bernoulli Double Uniform--mkBernoulli :: Uniform -> Double -> Bernoulli-mkBernoulli base p = Bernoulli p base--instance DiscreteDistribution Bernoulli where-  randIntIn (a, b) (Bernoulli p g0) =-    mapTuple-    (\x -> a + ((floor $ x + (1-p)) * (b-a)) )-    (Bernoulli p)-    (randDouble g0)-  randInt g0 = randIntIn (0, 1) g0--toDbl = fromInteger . toInteger
− src/Stochastic/Binomial.hs
@@ -1,20 +0,0 @@-module Stochastic.Binomial(Binomial, mkBinomial) where--import Stochastic.Distribution-import Stochastic.Bernoulli-import Helpers--data Binomial = Binomial Int Bernoulli--mkBinomial :: Bernoulli -> Int -> Binomial-mkBinomial base n = Binomial n base--instance DiscreteDistribution Binomial where-  randIntIn (a, b) (Binomial n g0) =-    mapTuple-    (\xs -> (a - 1) + (sum xs))-    (Binomial n)-    (randInts (b - a + 1) g0)-  randInt (Binomial n g0) = randIntIn (0, n) (Binomial n g0)--toDbl = fromInteger . toInteger
− src/Stochastic/Distribution.hs
@@ -1,26 +0,0 @@-{-# LANGUAGE DefaultSignatures #-}--module Stochastic.Distribution(ContinuousDistribution(..), DiscreteDistribution(..)) where--import Helpers(histogram, statefully)--class DiscreteDistribution g where-  randInt :: g -> (Int, g)-  randInt g = randIntIn (0, maxBound::Int) g-  randInts :: Int -> g -> ([Int], g)-  randInts n g0 = statefully (randInt) n g0-  randIntIn :: (Int, Int) -> g -> (Int, g)-  default randIntIn :: (ContinuousDistribution g) =>-                       (Int, Int) -> g -> (Int, g)-  randIntIn (a, b) g0 = ((ceiling (toDbl (b - a + 1) * d)) + (a-1), g1)-    where-      (d, g1) = randDouble g0-  --class ContinuousDistribution g where-  randDouble :: g -> (Double, g)-  randDoubles :: Int -> g -> ([Double], g)-  randDoubles n g0 = statefully (randDouble) n g0---toDbl = fromInteger . toInteger
+ src/Stochastic/Distribution/Continuous.hs view
@@ -0,0 +1,18 @@+module Stochastic.Distribution.Continuous where++import Stochastic.Tools++class ContinuousDistribution g where+  rand  :: g -> (Double, g)+  +  rands :: Int -> g -> ([Double], g)+  rands n g0 = statefully (rand) n g0++  cdf  :: g -> Double -> Double+  cdf' :: g -> Double -> Double+  +  pdf  :: g -> Double -> Double -> Double+  pdf g a b = (cdf g b) - (cdf g a)++  degreesOfFreedom :: g -> Int+  
+ src/Stochastic/Distribution/Discrete.hs view
@@ -0,0 +1,16 @@+module Stochastic.Distribution.Discrete where++import Stochastic.Tools++class DiscreteDistribution g where+  rand :: g -> (Int, g)++  rands :: Int -> g -> ([Int], g)+  rands n g0 = statefully (rand) n g0++  cdf  :: g -> Int -> Double+  +  cdf' :: g -> Double -> Int+  +  pmf  :: g -> Int -> Double+
src/Stochastic/Distributions.hs view
@@ -1,89 +1,72 @@+{-# LANGUAGE TypeFamilies #-} module Stochastic.Distributions(-  ContinuousDistribution(..)-  ,DiscreteDistribution(..)-  ,Distributions(..)-  ,mkDistributions-  ,stdDistributions-  ,liftD-  ,liftC-  ,liftDN-  ,liftCN---  ,plot+  UniformBase(rDouble)+  ,stdBase+  ,Empirical(..)+  ,mkEmpirical   ) where -import Helpers(histogram, statefully, mapTuple)-import Stochastic.Distribution+import System.Random+import Control.Monad.State.Lazy+import Stochastic.Tools -import qualified Stochastic.Uniform     as Uni-import qualified Stochastic.ZipF        as Zipf-import qualified Stochastic.Geometric   as Geo-import qualified Stochastic.Exponential as Exp-import qualified Stochastic.Poisson     as Poi-import qualified Stochastic.Normal      as Nor-import qualified Stochastic.Bernoulli   as Ber-import qualified Stochastic.Binomial    as Bin+data UniformBase = UniformBase {+  rDouble :: (Double, UniformBase)+} -data Distributions = Distributions {-  mkUniform    :: Int                     -> Uni.Uniform-  ,mkExp       :: Int -> Double           -> Exp.Exponential-  ,mkNormal    :: Int -> Double -> Double -> Nor.Normal -  ,mkZipF      :: Int -> Int    -> Double -> Zipf.ZipF-  ,mkGeometric :: Int -> Double           -> Geo.Geometric-  ,mkPoisson   :: Int -> Double           -> Poi.Poisson-  ,mkBernoulli :: Int -> Double           -> Ber.Bernoulli-  ,mkBinomial  :: Int -> Double -> Int    -> Bin.Binomial-}+stdGen2Uni gen = UniformBase {+  rDouble = mapTuple+            (id)+            (stdGen2Uni)+            (randomR (0,1) gen)+  } -stdDistributions = mkDistributions Uni.stdUniform+stdBase s = stdGen2Uni (mkStdGen s) -mkDistributions uniform = Distributions {-  mkUniform     = uniform-  , mkZipF      = apiMkZipF      (uniform)-  , mkGeometric = apiMkGeometric (uniform)-  , mkExp       = apiMkExp       (uniform)-  , mkPoisson   = apiMkPoisson   (uniform)-  , mkNormal    = apiMkNormal    (uniform)-  , mkBernoulli = apiMkBernoulli (uniform)-  , mkBinomial  = apiMkBinomial  (uniform)-} -apiMkZipF      mkUni seed n slope = Zipf.mkZipF      (mkUni seed) n slope-apiMkGeometric mkUni seed p       = Geo.mkGeometric  (mkUni seed) p-apiMkExp       mkUni seed y       = Exp.mkExp        (mkUni seed) y-apiMkPoisson   mkUni seed y       = Poi.mkPoisson $  apiMkExp (mkUni) seed y-apiMkNormal    mkUni seed m d     = Nor.mkNormal     (mkUni seed) m d-apiMkBernoulli mkUni seed d       = Ber.mkBernoulli  (mkUni seed) d-apiMkBinomial  mkUni seed d n     = Bin.mkBinomial   (apiMkBernoulli (mkUni) seed d) n+data Empirical = Empirical {+  degreesOfFreedom :: Int,+  cdf  :: Double -> Double,+  cdf' :: Double -> Double+  } -liftD :: (DiscreteDistribution g) => (Int, Int) -> (Int -> a) -> (g -> (a, g))-liftD range f g0 = ((f r), g1)+empiricalCDF' hist x = u - ((c - x)/s)   where-    (r, g1) = (randIntIn range g0)+    interval = head $ filter (\y -> cum_frequence y > x) $ hist+    u = upper_bound interval+    s = slope interval+    c = cum_frequence interval -liftDN :: (DiscreteDistribution g) => [(Int, Int)] -> ([Int] -> a) -> (g -> (a, g))-liftDN ranges f g0 = mapTuple (f) (id) (h ranges g0)+  +                 +empiricalCDF hist x+  | x <  (lower_bound $ head hist) = 0+  | x >= (upper_bound $ head $ reverse hist) = 1+  | otherwise =+    f $ filter (\y -> lower_bound y <= x  && upper_bound y >= x) hist   where-    h [] g1 = ([], g1)-    h (r:rs) g1 = let (s, g2) = randIntIn r g1 in mapTuple (\x -> s:x) (id) (h rs g2)+    f [] =+      error $ "x "++(show x)++" not in histogram range\n" +++      (foldr (\h str -> (show (lower_bound h, upper_bound h, frequency h)) ++ "\n" ++ str) "" hist)+    f (y:ys) =+      let part = (x - (lower_bound y)) in+      let step = part * slope y        in+      (cum_frequence y) + (step * (rel_frequence y))+     -liftC :: (ContinuousDistribution g) => (Double -> a) -> (g -> (a, g))-liftC f g0 = ((f r), g1)++mkEmpirical :: [Double] -> Empirical+mkEmpirical samples = Empirical {+  degreesOfFreedom = length h,+  cdf  = empiricalCDF h,+  cdf' = empiricalCDF' h+  }   where-    (r, g1) = (randDouble g0)+    h = fIHistogram samples+    count :: Double+    count = fromInteger . toInteger $ length samples -liftCN :: (ContinuousDistribution g) => Int -> ([Double] -> a) -> (g -> (a, g))-liftCN n f g0 = mapTuple (f) (id) (randDoubles n g0) -plot :: DiscreteDistribution g => g -> Int -> Int -> [Int]-plot g0 interval samples = []-{--plot g n samples = map (truncate . (+0.5) . (*100))-  $ map-  (\x ->-    (toDbl x)/(toDbl samples))-  $ histogram (1.0 / (toDbl n))-  (fst (randInts g samples))--}-toDbl = fromInteger . toInteger+ 
+ src/Stochastic/Distributions/Continuous.hs view
@@ -0,0 +1,90 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeFamilies #-}+module Stochastic.Distributions.Continuous(+  mkUniform+  ,mkExp+  ,mkNormal+  ,mkEmpirical+  ,Dist(..)+  ,ContinuousDistribution(..)+  ) where++import Data.Maybe+import Control.Monad.State.Lazy+--import Stochastic.Analysis+import Stochastic.Generator++import Stochastic.Distributions(UniformBase, rDouble)+import qualified Stochastic.Distributions as B(cdf, mkEmpirical, Empirical)+import Stochastic.Distribution.Continuous+import Stochastic.Tools+import Data.Number.Erf++instance ContinuousDistribution UniformBase where+  rand uni = rDouble uni+  cdf  _ x = x+  cdf' _ p = p+  degreesOfFreedom _ = 0+++instance Generator Dist where+  type (From Dist) = Double+  nextG = state $ \ g0 -> rand g0++instance Generator UniformBase where+  type (From UniformBase) = Double+  nextG = state $ \ g0 -> rDouble g0+++data Dist =+  Uniform UniformBase+  | Exponential Double UniformBase+  | Normal Double Double (Maybe Double) UniformBase+  | ChiSquared Int UniformBase+  | Empirical B.Empirical UniformBase+    -- empirical points, lo, [(point, mass)]++mkEmpirical :: UniformBase -> [Double] -> Dist+mkEmpirical base samples = Empirical (B.mkEmpirical samples) base++mkExp :: UniformBase -> Double -> Dist+mkExp base y = Exponential y base+mkNormal :: UniformBase -> Double -> Double -> Dist+mkNormal uni mean dev = Normal mean dev Nothing uni+mkUniform :: UniformBase -> Dist+mkUniform uni = Uniform uni++instance ContinuousDistribution Dist where+  rand (Uniform uni) = mapTuple (id) (Uniform) (rand uni)+  rand (Exponential y u) =+    mapTuple (\x -> (-1.0/y) * (log $ x)) (Exponential y) (rand u)+  rand (Normal mean dev m uni) = f m+    where+      f (Just x) = (x, (Normal mean dev Nothing uni'))+      f Nothing  = (y, (Normal mean dev (Just z) uni'))+      ([u1, u2], uni') = rands 2 uni+      from_u g = mean + dev * (sqrt (-2 * (log u1))) * ( g (2 * pi * u2) )+      y = from_u (sin)+      z = from_u (cos)++  cdf  (Uniform _) x = x+  cdf  (Exponential y _) x = 1 - (1 / (exp (y*x)))+  cdf  (Normal u s _ _) x =+    0.5 * (1 + (erf ((x-u)/(s * (sqrt 2))) ))+  cdf (ChiSquared k _) x = (1/(gamma (kd/2))) * lig+    where+      kd = fromInteger $ toInteger k+      lig = lower_incomplete_gamma (kd /2) (x/2)+  cdf (Empirical b _) x = B.cdf b x+         ++  cdf' (Uniform _) p = p+  cdf' (Exponential y _) p = -(log (1-p)) / y+  cdf' (Normal u s _ _) p =+    u + (s * (sqrt 2) * (inverf(2*p-1)))++  degreesOfFreedom (Uniform _) = 0+  degreesOfFreedom (Exponential _ _) = 1+  degreesOfFreedom (Normal _ _ _ _) = 2++
+ src/Stochastic/Distributions/Discrete.hs view
@@ -0,0 +1,171 @@+{-# LANGUAGE TypeFamilies #-}+module Stochastic.Distributions.Discrete(+  mkBinomial+  ,mkBernoulli+  ,mkPoisson+  ,mkZipF+  ,mkGeometric+  ,Stochastic.Distributions.Discrete.Dist(..)+  ,DiscreteDistribution(..)+  ) where++import Data.Maybe+import Control.Monad.State.Lazy+import Stochastic.Tools+import Stochastic.Generator(Generator(..), foldWhile)+import Stochastic.Distributions+import Stochastic.Distribution.Discrete+import qualified Stochastic.Distributions.Continuous as C++instance Generator Dist where+  type (From Dist) = Int+  nextG = state $ \ g0 -> rand g0++data Dist =+  Uniform Int Int UniformBase+  | Poisson C.Dist+  | Geometric Double UniformBase+  | Bernoulli Double UniformBase+  | Binomial Int Double DiscreteCache UniformBase+  | ZipF Int Double DiscreteCache UniformBase++mkBinomial :: UniformBase -> Double -> Int -> Dist+mkBinomial base p n = Binomial n p cache base+  where+    nd = toDbl n+    cache :: DiscreteCache+    cache = foldr (\(w,x,y,z) l -> (w,y,z):l) [] (create n)+    create :: Int -> [(Int, Double, Double, Double)]+    create 0 = let pmfk = (nd * (log (1 - p)) )+               in [(0, pmfk, exp pmfk, exp pmfk)]+    create k = (k, lpmfk, pmfk, cdfk) : sub+      where+        sub = create (k-1)+        (j, lpmfj, pmfj, cdfj) = head sub+        pmfk = exp lpmfk+        kd = toDbl k+        lpmfk = lpmfj ++                (log p) - (log (1- p)) -+                (log (kd)) + (log (nd-kd+1))+        cdfk = pmfk + cdfj+        +-- k, pmf k, cdf k+-- do in log space+type DiscreteCache = [(Int, Double, Double)]++mkUniform :: UniformBase -> Int -> Int -> Dist+mkUniform base a b = Uniform a b base++mkBernoulli :: UniformBase -> Double -> Dist+mkBernoulli base p = Bernoulli p base++mkPoisson :: UniformBase -> Double -> Dist+mkPoisson base y = Poisson (C.mkExp base y)++mkGeometric :: UniformBase -> Double -> Dist+mkGeometric base p = Geometric p base++mkZipF :: UniformBase -> Int -> Double -> Dist+mkZipF base n slope = ZipF n slope cache base+  where+    hns = sum $ take n $ harmonics slope+    cache :: DiscreteCache+    cache = create n+    create :: Int -> DiscreteCache+    create 1 = let pmfk = 1 / hns in [(1,pmfk,pmfk)]+    create k =+      (k, (1/(((toDbl k)**slope) * hns)), cdfj + pmfj) : sub+      where+        sub             = create (k-1)+        (j, pmfj, cdfj) = head sub++instance DiscreteDistribution Dist where+  rand (Binomial n p cache g0) =+    mapTuple+    (\u -> +      length $ filter (pred u) cache)+    (Binomial n p cache)+    (C.rand g0)+    where pred u (k, pmf, cdf) = cdf < u+  rand (Geometric p g0) =+    mapTuple+    (\u -> ceiling $ (log u) / (log (1-p)))+    (Geometric p)+    (C.rand g0)+  rand (Poisson g0@(C.Exponential y u)) =+    mapTuple+    (\x -> length x)+    (Poisson)+    (runState (foldWhile (+) 0.0 (<1.0)) g0)+  rand (Bernoulli p g0) =+    mapTuple+    (\x -> if (x >= p) then 1 else 0)+    (Bernoulli p)+    (C.rand g0)+  rand (ZipF n slope cache u0) = +    mapTuple+    (\u ->+      length $ filter (pred u) cache)+    (ZipF n slope cache)+    (C.rand u0)+    where pred u (k, pmf, cdf) = cdf < u+  rand (Uniform a b g0) =+    mapTuple+    (\x -> truncate (toDbl (b - a) * x + toDbl a))+    (Uniform a b)+    (C.rand g0)++  cdf (Poisson (C.Exponential y _)) x =+    (1/(exp y)) * (sum [ (y ** (toDbl i)) / (fromInteger $ fac i) | i <- [0..x]])+  cdf (Geometric p _) x = 1 - (1-p)^x+  cdf (Bernoulli p _) x+    | x < 0     = 0+    | x >= 1    = 1+    | otherwise = p+  cdf (Binomial n p cache _) x = r+    where+      (_, _, r) = head $ filter (\(w,_,_) -> (w==x)) cache+  cdf (ZipF n s cache _) x = r+    where+      (_, _, r) =+        head $ filter (\(k, _, _) -> x == k) cache +  cdf (Uniform a b _) x = toDbl (x-a) / toDbl (b-a)++  cdf' g@(Poisson (C.Exponential y _)) x =+    sum . fst $ runState (fold) [1..]+    where+      reduce :: Int -> Double -> Double+      reduce = (\y p -> (pmf g y) + p)+      fold :: State [Int] [From [Int]]+      fold = foldWhile (reduce) 0 (<x)+  cdf' (Geometric p _) x =+    ceiling $ (log (1-x)) / (log (1-p))+  cdf' (Bernoulli p _) x+    | x > p     = 1+    | otherwise = 0+  cdf' (Binomial n p cache _) x = r+    where+      (r, _, _) =+        head $ reverse $ filter (\(_, _, z) -> z > x) cache+  cdf' (ZipF n s cache _) x = r+    where+      (r, _, _) =+        head $ reverse $ filter (\(_, _, z) -> z > x) cache+  cdf' (Uniform a b _) x = truncate $ toDbl (b-a) * x + toDbl a+  +  pmf (Poisson (C.Exponential y _)) x =+    (y^x) / ( exp y * (fromInteger $ fac x) )+  pmf (Geometric p _) x = 1 - (1-p)^(x-1)+  pmf (Bernoulli p _) 0 = 1-p+  pmf (Bernoulli p _) 1 = p+  pmf (Binomial n p cache _) x = r+    where+      (_, r, _) = head $ filter (\(w,_,_) -> (w==x)) cache+  pmf (ZipF n s cache _) k = r+    where+      (_, r, _) = head $ filter (\(w,_,_) -> (w==k)) cache+  pmf (Uniform a b _) x = toDbl x/toDbl (b-a)+++toDbl = fromInteger . toInteger+
− src/Stochastic/Exponential.hs
@@ -1,19 +0,0 @@-module Stochastic.Exponential(Exponential, mkExp) where--import Stochastic.Distribution-import Stochastic.Uniform-import Data.Word-import Data.ReinterpretCast-import Helpers--data Exponential = Exponential Double Uniform--viaWord :: Double -> Int-viaWord w =  fromInteger $ toInteger $ doubleToWord w--mkExp :: Uniform -> Double -> Exponential-mkExp base y = Exponential y base--instance ContinuousDistribution Exponential where-  randDouble (Exponential y u) =-    mapTuple (\x -> (-1.0/y) * (log $ x)) (Exponential y) (randDouble u)
+ src/Stochastic/Generator.hs view
@@ -0,0 +1,45 @@+{-# LANGUAGE TypeFamilies #-}+module Stochastic.Generator where++import Control.Monad.State.Lazy++class Generator g where+  type From g+  nextG   :: State g (From g)+  nextN  :: Int -> State g [(From g)]+  nextN 0 = state $ \g0 -> ([], g0)+  nextN n =+    do+      x  <- nextG+      xs <- nextN (n-1)+      return (x:xs)++instance Generator [a] where+  type From [a] = a+  nextG = state $ \ g0 -> (head g0, tail g0)++foldWhile :: Generator g+         => (From g -> a -> a)+         -> a+         -> (a -> Bool)+         -> State g [From g]+foldWhile f z p =+  do+   x  <- nextG+   let y = f x z+   xs <- if (p y)+         then foldWhile f y p +         else return []+   return (x:xs)++while :: Generator g => ((From g) -> Bool) -> State g [From g]+while p =+  do+   x  <- nextG+   xs <- if (p x)+         then while p+         else return []+   return (x:xs)+++
− src/Stochastic/Geometric.hs
@@ -1,23 +0,0 @@-module Stochastic.Geometric (mkGeometric, Geometric) where--import Stochastic.Distribution-import Stochastic.Uniform-import Helpers--data Geometric = Geometric Double Uniform--mkGeometric :: Uniform -> Double -> Geometric-mkGeometric base p = Geometric p base--instance DiscreteDistribution Geometric where-  randIntIn (a, b) (Geometric p g0) = mapTuple-               (\u -> trunc $ invert u)-               (Geometric p)-               (randDouble g0)-    where-      invert u = ceiling $ (log u) / (log (1-p))-      trunc x-        | x > (b-a) = b-        | otherwise = a+x--toDbl = fromInteger . toInteger
− src/Stochastic/Normal.hs
@@ -1,25 +0,0 @@-module Stochastic.Normal(mkNormal, Normal) where--import Data.Maybe-import Stochastic.Distribution-import Stochastic.Uniform-import Helpers--data Normal = Normal Double Double (Maybe Double) Uniform--mkNormal :: Uniform -> Double -> Double -> Normal-mkNormal uni mean dev = Normal mean dev Nothing uni--toDbl :: Int -> Double-toDbl = fromInteger . toInteger--instance ContinuousDistribution Normal where-  randDouble (Normal mean dev m uni) = f m-    where-      f (Just x) = (x, (Normal mean dev Nothing uni))-      f Nothing  = (y, (Normal mean dev (Just z) uni))-      ([u1, u2], uni') = randDoubles 2 uni-      from_u g = mean + dev * (sqrt (-2 * (log u1))) * ( g (2 * pi * u2) )-      y = from_u (sin)-      z = from_u (cos)-    
− src/Stochastic/Poisson.hs
@@ -1,24 +0,0 @@-module Stochastic.Poisson(mkPoisson, Poisson) where--import Stochastic.Distribution-import Stochastic.Exponential-import Helpers--data Poisson = Poisson Exponential--mkPoisson :: Exponential -> Poisson-mkPoisson base = Poisson base--toDbl :: Int -> Double-toDbl = fromInteger . toInteger--instance DiscreteDistribution Poisson where-  randIntIn (a, b) (Poisson g0) = mapTuple-                                  (\x -> min (x+a-1) b)-                                  (Poisson)-                                  (f 0 0 g0)-    where-      f x s g1-        | s > 1     = (x-1, g1)-        | otherwise = f (x+1) (s+y) g2-          where (y, g2) = (randDouble g1)
+ src/Stochastic/Tools.hs view
@@ -0,0 +1,182 @@+{-# LANGUAGE TypeFamilies #-}+module Stochastic.Tools where++import Control.Monad.State.Lazy+import Data.Maybe+import qualified Data.Map as Map+import Data.List(sort)++maybeHead :: [a] -> Maybe a+maybeHead []     = Nothing+maybeHead (x:xs) = Just x++headOrElse :: a -> [a] -> a+headOrElse d ls = fromMaybe d (maybeHead ls)++mapTuple :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)    +mapTuple f g (x, y) = (f x, g y)++histogram :: Double -> [Double] -> [Int]+histogram precision ls = map lookup0 [0..limit]+  where+    limit = truncate $ (1.0 / precision)+    divs = map (\x -> x / precision) ls+    ints = map (truncate) divs+    m   = foldl+          (\b a ->+            Map.insert a ((fromMaybe 0 (Map.lookup a b))+1) b)+          Map.empty+          ints+    lookup0 = (\x -> fromMaybe 0 $ Map.lookup x m)++comb :: Int -> Int -> Double+comb n k =+  (fromInteger $ foldr (*) 1 ls) / (fromInteger $ fac (n-k))+  where+    ls = [(toInteger k)..(toInteger n)]+++gamma :: Double -> Double+gamma = stirlingsApprox++lower_incomplete_gamma :: Double -> Double -> Double+lower_incomplete_gamma = estimate_lower_gamma 10++estimate_lower_gamma n s x = (x**s)*(gamma s) * (exp (-x)) * approx+  where+    approx = sum $ fmap term [0..n]+    term k = (x**k) / (gamma (s + k + 1))++stirlingsApprox n +  | n < 0.5   = stirlingsApprox (1-n)+  | otherwise = (sqrt (2*pi*n)) * (exp $ n * ((log n) - 1))++fac :: Int -> Integer+fac n = head $ drop (n-1) factorial++factorial :: [Integer]+factorial = 1 : 1 : (tail (zipWith (*) (factorial) [1..]))++fib :: Int -> Integer+fib n = head $ drop (n-1) fibinacci++fibinacci :: [Integer]+fibinacci = 1 : 1 : (zipWith (+) fibinacci (tail fibinacci))++harmonics :: Double -> [Double]+harmonics s = (h 1)+  where+    h n = (1.0/(n**s)) : h (n+1)++statefully :: (g -> (a, g)) -> Int -> g -> ([a], g)+statefully f n g0 = case n of+    0 -> ([], g0)+    x -> (r:rest, g2)+      where+        (r, g1) = f g0+        (rest, g2) = statefully f (n-1) g1++statefullyTakeWhile :: (g -> (a, g)) ->+                       ([a] -> Bool) ->+                       g ->+                       ([a], g)+statefullyTakeWhile f p g0 = r ([], g0)+  where+    r (list, g1)+      | p list    = (list, g1)+      | otherwise = mapTuple (\l -> l:list) (id) (f g1)++type Histogram = [Datagram]+data Datagram = Datagram {+  lower_bound :: Double,+  upper_bound :: Double,+  frequency :: Int,+  rel_frequence :: Double,+  cum_frequence :: Double,+  slope :: Double+  } deriving (Show, Eq)++++--peice wise linear +fIHistogram :: [Double] -> Histogram+fIHistogram list =+  datagramFromRaw len iSize $ bin (lowerOf iSize) list+  where+    toDbl = fromInteger . toInteger+    len = length list+    iSize :: Double+    iSize = (maxf list -+             minf list) /+            iCount+    iCount = sqrt (toDbl $ len)++maxf (x:xs) = foldl (max) x xs+minf (x:xs) = foldl (min) x xs++datagramFromRaw :: Int -> Double -> [(Double, Int)] -> [Datagram]+datagramFromRaw count iSize = accMap f z+  where+    f acc (x, c)  = Datagram {+      lower_bound = x,+      upper_bound = x + iSize,+      frequency = c,+      rel_frequence = rf,+      cum_frequence = rf + (cum_frequence acc),+      slope = rf / iSize+      }+      where rf = (toDbl c / toDbl count)+    z (x, c) = Datagram {+      lower_bound = x,+      upper_bound = x + iSize,+      frequency = c,+      rel_frequence = rf,+      cum_frequence = rf,+      slope = rf / iSize+      }+      where rf = (toDbl c / toDbl count)+    toDbl = fromInteger . toInteger++accMap :: (b -> a -> b) -> (a -> b) -> [a] -> [b]+accMap f z ls = g (z $ head ls) (tail ls)+  where+    g prev []     = []+    g prev (x:xs) = new : (g new xs)+      where new = (f prev x)+{-+Takes the set +w : x : y : z : []+and produces the set +(f w x) : (f x y) : (f y z) : []+-}    +biFold :: (a -> a -> b) -> [a] -> [b]+biFold f = g+  where+    g []  = []+    g [x] = []+    g (x:y:ys) = (f x y) : (g (y:ys))++dependentMap :: (a -> a -> b) -> (a -> b) -> [a] -> [b]+dependentMap f z xs = (z $ head xs) : (biFold f xs)+    +    +bin :: (Double -> Double) -> [Double] -> [(Double, Int)]+bin lowerOf ls = group $ map (lowerOf) ls++lowerOf :: Double -> Double -> Double+lowerOf iSize v = iSize * (fromInteger $ truncate (v / iSize))+++    +group :: (Ord a) => [a] -> [(a, Int)]+group = groupSeq . sort+    +groupSeq :: (Eq a) => [a] -> [(a, Int)]+groupSeq list = foldr g [] list+  where+    g x [] = [(x, 1)]+    g x ((y,c):ys)+      | x == y    = (y, c+1):ys+      | otherwise = (x, 1):(y,c):ys++
− src/Stochastic/Uniform.hs
@@ -1,22 +0,0 @@-module Stochastic.Uniform (Uniform(..)-                          , stdUniform) where--import Helpers-import System.Random-import Stochastic.Distribution---instance ContinuousDistribution Uniform where-  randDouble uni = rDouble uni --data Uniform = Uniform {-  rDouble :: (Double, Uniform)-}--stdGen2Uni gen = Uniform {-  rDouble = mapTuple (id) (stdGen2Uni) (randomR (0,1) gen)-  }--stdUniform s = stdGen2Uni (mkStdGen s)--
− src/Stochastic/ZipF.hs
@@ -1,45 +0,0 @@-module Stochastic.ZipF (mkZipF, ZipF) where--import Helpers-import Stochastic.Uniform-import Data.Maybe-import Stochastic.Distribution--data ZipF = ZipF Int Double Uniform--mkZipF :: Uniform -> Int -> Double -> ZipF-mkZipF base n slope = ZipF n slope base---- index, number, cumlative-harmonics :: Double -> [(Double, Double, Double)]-harmonics s = (h 1 0)-  where-    h n acc = (n, v, v+acc) : h (n+1) (v+acc)-      where-        v = (1.0/(n**s))--toDbl = fromInteger . toInteger--f n s d = h2 $ h1 hs-  where-    hs      = harmonics s-    mx      = _3 $ head $ drop (n-1) $ take n $ hs-    h1 xs    = headOrElse (toDbl n, 0, 0) $-              (dropWhile (\(i, v, c) -> c < (d * mx))) (take (n) xs)-    h2 (x, _, _) = truncate x-  -g = f 10 1--instance DiscreteDistribution ZipF where-  randIntIn (a, b) (ZipF n slope u0) = (f n slope d, ZipF n slope u1)-    where-      (d, u1) = randDouble u0--_1 :: (a, b, c) -> a-_1 (x, y, z) = x--_3 :: (a, b, c) -> c-_3 (x, y, z) = z---
+ tests/unit.hs view
@@ -0,0 +1,149 @@+import Stochastic.Distributions+import Stochastic.Analysis+import Stochastic.Tools+import qualified Stochastic.Distributions.Continuous as C+import qualified Stochastic.Distributions.Discrete as D+import Test.HUnit+import Data.Monoid+import Control.Monad+--import Utils+import Control.Monad (unless)++tests = TestList [+  TestLabel "Binomial pmf" bpmf1+  ,TestLabel "ZipF pmf" zipFpmf1+  ,TestLabel "Normal cdf 0" normalCDF0+  ,TestLabel "Normal cdf 1" normalCDF1+  ,TestLabel "Normal cdf 2" normalCDF2+  ,TestLabel "Normal cdf 3" normalCDF3+  ,TestLabel "Normal ChiSquared" chinorm+  ,TestLabel "Exponential ChiSquared" chiexp+  ,TestLabel "Uniform ChiSquared" chiuni+  ,TestLabel "Poisson ChiSquared" chiPoisson+  ,TestLabel "Test of grouping" groupTest+--  ,TestLabel "Test histogram" binTest+  ]+++--+-- Discrete Tests+--+bpmf1 = TestCase (assertWithinDelta "binomial's pmf must sum to 1" (1e-15) e a)+  where+    b = D.mkBinomial (stdBase 42) 0.4 10+    e = 1+    a = sum [ D.pmf b k | k <- [0..10] ]++zipFpmf1 = TestCase (assertWithinDelta "ZipF's pmf must sum to 1" (1e-15) e a)+  where+    b = D.mkZipF (stdBase 42) 10 1+    e = 1+    a = sum [ D.pmf b k | k <- [1..10] ]++--+-- Continuous Tests+--++stdNormal = C.mkNormal (stdBase 42) 0 1++normalCDF0 = TestCase (assertWithinDelta+                       "Normal CDF at 0 standard deviations"+                       (1e-15) 0.5    $ C.cdf stdNormal 0)+normalCDF1 = TestCase (assertWithinDelta+                       "Normal CDF at 1 standard deviations"+                       (1e-4)  0.8413 $ C.cdf stdNormal 1)+normalCDF2 = TestCase (assertWithinDelta+                       "Normal CDF at 2 standard deviations"+                       (1e-4)  0.9772 $ C.cdf stdNormal 2)+normalCDF3 = TestCase (assertWithinDelta+                       "Normal CDF at 0 standard deviations"+                       (1e-4)  0.9987 $ C.cdf stdNormal 3)++--+-- Stochastic Tests+--++chiTestRandom :: C.Dist+                 -> Double+chiTestRandom g = chiSquaredTest g (mkEmpirical samples) bounds+  where+    (samples, _) = C.rands 1000 g+    hist = fIHistogram samples+    bounds = fmap (lower_bound) hist++chinorm = TestCase (+  assertWithinDelta+  "Sample of the normal distribution passes the ChiSquaredTest with HIGH confidence"+  (2e-1) 0 (chiTestRandom stdNormal))++chiuni = TestCase (+  assertWithinDelta+  "Sample of the uniform distribution passes the ChiSquaredTest with HIGH confidence"+  (1e-1) 0 (chiTestRandom $ C.mkUniform $ stdBase 42))++chiexp = TestCase (+  assertWithinDelta+  "Sample of the exponential distribution passes the ChiSquaredTest with HIGH confidence"+  (2e-1) 0 (chiTestRandom $ C.mkExp (stdBase 42) 1))++groupTest = TestCase+            (assertEqual+             "groups where non optimal"+             ([(1,2), (2,3), (3,1)])+             (group [2,1,1,2,2,3])+            )++chiPoisson = TestCase (+  assertWithinDelta+  "Sample of the poisson distribution passes the ChiSquaredTest with HIGH confidence"+  (2e-1) 0 (chiTestDiscreteRandom $ D.mkPoisson (stdBase 42) 1))++chiTestDiscreteRandom :: D.Dist+                      -> Double+chiTestDiscreteRandom g = discreteChiSquaredTest g (mkEmpirical samples) bounds+  where+    samples = fmap (toDbl) $ fst $ D.rands 1000 g+    hist = fIHistogram samples+    bounds = fmap (fromDbl . lower_bound) hist+    toDbl = fromInteger . toInteger+    fromDbl = fromInteger . truncate++            +{-+binTest = TestCase+          (assertEqual+           "bins had holes"+           ([])+           (fmap (\x -> (lower_bound x, upper_bound x, frequency x))+            $ fIHistogram samples)+          )+  where+    (samples, _) = C.rands 1000 stdNormal+-}++{-+ let norm = mkNormal (stdBase 42) 0 1 in                                let (samples,_) = rands 1000 norm in                                   let emp = mkEmpirical samples in                                       let hist = fIHistogram samples in                                      let bounds = fmap (lower_bound) hist in                                let chi = chiSquaredTest norm emp bounds in                            let imp = fmap (\x -> (lower_bound x, frequency x, C.cdf norm (lower_bound x), C.cdf emp (lower_bound x)) ) hist in mapM (putStrLn.show) imp-}++--+-- Custom Assertions+--++assertWithinDelta ::   String  -- ^ The message prefix+               -> Double  -- ^ The maximum difference between expected and actual+               -> Double  -- ^ The expected value+               -> Double  -- ^ The actual value+               -> Assertion+assertWithinDelta preface delta expected actual = +  unless passed (assertFailure msg)+  where+    passed = (abs (expected - actual) < delta)+    msg = (if null preface then "" else preface ++ "\n") +++          "expected: " ++ show expected ++ "\n but got: " ++ show actual+  +++main :: IO ()+main =+  do+    counts <- runTestTT tests+    return ()
+ tests/vis.hs view
@@ -0,0 +1,29 @@+import Stochastic.Generator+import Stochastic.Distribution.Continuous+import Stochastic.Distributions+import Stochastic.Distributions.Continuous+import System.Directory+import System.IO++dumpSamples :: (String, [Double]) -> IO ()+dumpSamples  (gen_name, samples) = do+  _ <- createDirectoryIfMissing True "dist/samples"+  _ <- withFile+       ("dist/samples/" ++ gen_name ++ ".dat")+       WriteMode+       (\handle -> mapM_+                   (hPrint handle)+                   samples+       )+  return ()++cds seed sample_size = [+  ("uniform",          fst $ rands sample_size $ mkUniform (stdBase seed)    )+  ,("exponential",     fst $ rands sample_size $ mkExp     (stdBase seed)   1)+  ,("normal",          fst $ rands sample_size $ mkNormal  (stdBase seed) 0 1)+  ]++main :: IO ()+main =+  let gens = cds 42 100000 in+  mapM_ (dumpSamples) gens