monte-carlo 0.3.1 → 0.4
raw patch · 12 files changed
+300/−91 lines, 12 filesdep ~gsl-random
Dependency ranges changed: gsl-random
Files
- NEWS +13/−1
- examples/Poker.hs +1/−1
- lib/Control/Monad/MC/Base.hs +75/−9
- lib/Control/Monad/MC/Class.hs +2/−2
- lib/Control/Monad/MC/GSL.hs +1/−1
- lib/Control/Monad/MC/GSLBase.hs +92/−35
- lib/Control/Monad/MC/Repeat.hs +2/−2
- lib/Control/Monad/MC/Sample.hs +94/−20
- lib/Data/Summary/Bool.hs +4/−4
- lib/Data/Summary/Double.hs +5/−5
- lib/Data/Summary/Utils.hs +1/−1
- monte-carlo.cabal +10/−10
NEWS view
@@ -1,3 +1,15 @@+Changes in 0.4:++* Felipe Lessa added applicative instances to GSL's MC and MCT.++* Felipe Lessa added many distributions: beta, logistic, Pareto, Weibull, gamma,+ multinomial and Dirichlet distributions are now available.++* Change argument order of subset sampling functions.++* Add weighted sampling without replacement.++ Changes in 0.3.1: * Change upper bound on vector dependency.@@ -27,7 +39,7 @@ * The pure RNG is now a newtype, so you can't use the functions from GLS.Random.Gen on it anymore.- + * The internals of the monad have been cleaned up. IO is used internally instead of `seq` calls and `unsafePerformIO` everywhere. This results in a modest performance boost.
examples/Poker.hs view
@@ -61,7 +61,7 @@ -- | Deal a five-card hand by choosing a random subset of the deck. deal :: (MonadMC m) => m [Card]-deal = sampleSubset 5 deck+deal = sampleSubset deck 5 -- | A type for storing the frequencies of the various hands. type HandCounts = Map Hand Int
lib/Control/Monad/MC/Base.hs view
@@ -14,6 +14,8 @@ import Control.Monad import qualified Control.Monad.MC.GSLBase as GSL +import qualified Data.Vector.Storable as VS+ class HasRNG m where -- | The random number generator type for the monad. type RNG m@@ -21,17 +23,17 @@ class (Monad m, HasRNG m) => MonadMC m where -- | Get the current random number generator. getRNG :: m (RNG m)- + -- | Set the current random number generator. setRNG :: RNG m -> m ()- + -- | @uniform a b@ generates a value uniformly distributed in @[a,b)@. uniform :: Double -> Double -> m Double- + -- | @uniformInt n@ generates an integer uniformly in the range @[0,n-1]@. -- It is an error to call this function with a non-positive value. uniformInt :: Int -> m Int- + -- | @normal mu sigma@ generates a Normal random variable with mean -- @mu@ and standard deviation @sigma@. normal :: Double -> Double -> m Double@@ -43,15 +45,47 @@ -- exponent @alpha@. The algorithm only works for @0 < alpha <= 2@. levy :: Double -> Double -> m Double - -- | @levySkew c alpha beta @ gets a skew Levy alpha-stable variate + -- | @levySkew c alpha beta @ gets a skew Levy alpha-stable variate -- with scale @c@, exponent @alpha@, and skewness @beta@. The skew -- parameter must lie in the range @[-1,1]@. The algorithm only works -- for @0 < alpha <= 2@. levySkew :: Double -> Double -> Double -> m Double- + -- | @poisson mu@ generates a Poisson random variable with mean @mu@. poisson :: Double -> m Int- ++ -- | @cauchy a@ generates a Cauchy random variable with scale+ -- parameter @a@.+ cauchy :: Double -> m Double++ -- | @beta a b@ generates a beta random variable with+ -- parameters @a@ and @b@.+ beta :: Double -> Double -> m Double++ -- | @logistic a@ generates a logistic random variable with+ -- parameter @a@.+ logistic :: Double -> m Double++ -- | @pareto a b@ generates a Pareto random variable with+ -- exponent @a@ and scale @b@.+ pareto :: Double -> Double -> m Double++ -- | @weibull a b@ generates a Weibull random variable with+ -- scale @a@ and exponent @b@.+ weibull :: Double -> Double -> m Double++ -- | @gamma a b@ generates a gamma random variable with+ -- parameters @a@ and @b@.+ gamma :: Double -> Double -> m Double++ -- | @multinomial n ps@ generates a multinomial random+ -- variable with parameters @ps@ formed by @n@ trials.+ multinomial :: Int -> VS.Vector Double -> m (VS.Vector Int)++ -- | @dirichlet alphas@ generates a Dirichlet random variable+ -- with parameters @alphas@.+ dirichlet :: VS.Vector Double -> m (VS.Vector Double)+ -- | Get the baton from the Monte Carlo monad without performing any -- computations. Useful but dangerous. unsafeInterleaveMC :: m a -> m a@@ -86,6 +120,22 @@ {-# INLINE levySkew #-} poisson = GSL.poisson {-# INLINE poisson #-}+ cauchy = GSL.cauchy+ {-# INLINE cauchy #-}+ beta = GSL.beta+ {-# INLINE beta #-}+ logistic = GSL.logistic+ {-# INLINE logistic #-}+ pareto = GSL.pareto+ {-# INLINE pareto #-}+ weibull = GSL.weibull+ {-# INLINE weibull #-}+ gamma = GSL.gamma+ {-# INLINE gamma #-}+ multinomial = GSL.multinomial+ {-# INLINE multinomial #-}+ dirichlet = GSL.dirichlet+ {-# INLINE dirichlet #-} unsafeInterleaveMC = GSL.unsafeInterleaveMC {-# INLINE unsafeInterleaveMC #-} @@ -104,12 +154,28 @@ normal mu sigma = GSL.liftMCT $ GSL.normal mu sigma {-# INLINE normal #-} exponential mu = GSL.liftMCT $ GSL.exponential mu- {-# INLINE exponential #-} + {-# INLINE exponential #-} levy c alpha = GSL.liftMCT $ GSL.levy c alpha {-# INLINE levy #-}- levySkew c alpha beta = GSL.liftMCT $ GSL.levySkew c alpha beta+ levySkew c alpha beta_ = GSL.liftMCT $ GSL.levySkew c alpha beta_ {-# INLINE levySkew #-} poisson mu = GSL.liftMCT $ GSL.poisson mu {-# INLINE poisson #-}+ cauchy a = GSL.liftMCT $ GSL.cauchy a+ {-# INLINE cauchy #-}+ beta a b = GSL.liftMCT $ GSL.beta a b+ {-# INLINE beta #-}+ logistic a = GSL.liftMCT $ GSL.logistic a+ {-# INLINE logistic #-}+ pareto a b = GSL.liftMCT $ GSL.pareto a b+ {-# INLINE pareto #-}+ weibull a b = GSL.liftMCT $ GSL.weibull a b+ {-# INLINE weibull #-}+ gamma a b = GSL.liftMCT $ GSL.gamma a b+ {-# INLINE gamma #-}+ multinomial n ps = GSL.liftMCT $ GSL.multinomial n ps+ {-# INLINE multinomial #-}+ dirichlet alphas = GSL.liftMCT $ GSL.dirichlet alphas+ {-# INLINE dirichlet #-} unsafeInterleaveMC = GSL.unsafeInterleaveMCT {-# INLINE unsafeInterleaveMC #-}
lib/Control/Monad/MC/Class.hs view
@@ -14,10 +14,10 @@ -- * The Monte Carlo monad type class HasRNG(..), MonadMC(..),- + -- * Random distributions bernoulli,- + module Control.Monad.MC.Sample, module Control.Monad.MC.Repeat, ) where
lib/Control/Monad/MC/GSL.hs view
@@ -15,7 +15,7 @@ runMC, evalMC, execMC,- + -- * The Monte Carlo monad transformer MCT, runMCT,
lib/Control/Monad/MC/GSLBase.hs view
@@ -15,7 +15,7 @@ evalMC, execMC, unsafeInterleaveMC,- + -- * The Monte Carlo monad transformer MCT(..), runMCT,@@ -45,9 +45,18 @@ levy, levySkew, poisson,+ cauchy,+ beta,+ logistic,+ pareto,+ weibull,+ gamma,+ multinomial,+ dirichlet, ) where -import Control.Monad ( liftM, MonadPlus(..) )+import Control.Applicative ( Applicative(..), (<$>) )+import Control.Monad ( ap, liftM, MonadPlus(..) ) import Control.Monad.Cont ( MonadCont(..) ) import Control.Monad.Error ( MonadError(..) ) import Control.Monad.Reader ( MonadReader(..) )@@ -56,7 +65,9 @@ import Control.Monad.Trans ( MonadTrans(..), MonadIO(..) ) import Data.Word import System.IO.Unsafe ( unsafePerformIO, unsafeInterleaveIO )- ++import qualified Data.Vector.Storable as VS+ import qualified GSL.Random.Gen as GSL import GSL.Random.Dist @@ -71,7 +82,7 @@ a <- g r' return (a,RNG r') {-# NOINLINE runMC #-}- + -- | Evaluate this Monte Carlo monad and throw away the final random number -- generator. Very much like @fst@ composed with @runMC@. evalMC :: MC a -> RNG -> a@@ -93,16 +104,20 @@ instance Monad MC where return a = MC $ \_ -> return a {-# INLINE return #-}- + (MC m) >>= k = MC $ \r -> m r >>= \a -> let (MC m') = k a in m' r {-# INLINE (>>=) #-}- + fail s = MC $ \_ -> fail s {-# INLINE fail #-} +instance Applicative MC where+ pure = return+ (<*>) = ap+ -- | A parameterizable Monte Carlo monad for encapsulating an inner -- monad. newtype MCT m a = MCT (GSL.RNG -> IO (m a))@@ -111,7 +126,7 @@ runMCT :: (Monad m) => MCT m a -> RNG -> m (a,RNG) runMCT (MCT g) (RNG r) = unsafePerformIO $ do r' <- GSL.cloneRNG r- ma <- g r' + ma <- g r' return (ma >>= \a -> return (a, RNG r')) {-# NOINLINE runMCT #-} @@ -120,8 +135,8 @@ evalMCT g r = do ~(a,_) <- runMCT g r return a- --- | Similar to 'execMC'. ++-- | Similar to 'execMC'. execMCT :: (Monad m) => MCT m a -> RNG -> m RNG execMCT g r = do ~(_,r') <- runMCT g r@@ -135,7 +150,7 @@ {-# INLINE liftMCT #-} unsafeInterleaveMCT :: (Monad m) => MCT m a -> MCT m a-unsafeInterleaveMCT (MCT g) = MCT $ \r -> +unsafeInterleaveMCT (MCT g) = MCT $ \r -> unsafeInterleaveIO (g r) {-# INLINE unsafeInterleaveMCT #-} @@ -143,12 +158,12 @@ fmap f (MCT g) = MCT $ \r -> do ma <- g r return (ma >>= return . f)- {-# INLINE fmap #-} + {-# INLINE fmap #-} instance (Monad m) => Monad (MCT m) where return a = MCT $ \_ -> return (return a) {-# INLINE return #-}- + (MCT g) >>= k = MCT $ \r -> do ma <- g r@@ -156,15 +171,19 @@ let (MCT m') = k a in unsafePerformIO $ m' r {-# NOINLINE (>>=) #-}- + fail str = MCT $ \_ -> fail str {-# INLINE fail #-} +instance (Monad m) => Applicative (MCT m) where+ pure = return+ (<*>) = ap+ instance (MonadPlus m) => MonadPlus (MCT m) where mzero = MCT $ \_ -> mzero {-# INLINE mzero #-}- - (MCT m) `mplus` (MCT n) = ++ (MCT m) `mplus` (MCT n) = MCT $ \r -> do r' <- GSL.cloneRNG r mr <- m r@@ -185,11 +204,11 @@ instance (MonadError e m) => MonadError e (MCT m) where throwError = lift . throwError {-# INLINE throwError #-}- + (MCT g) `catchError` h = MCT $ \r -> do ma <- g r- return $ ma `catchError` \e -> - let (MCT m') = h e + return $ ma `catchError` \e ->+ let (MCT m') = h e in unsafePerformIO (m' r) {-# NOINLINE catchError #-} @@ -200,28 +219,28 @@ instance (MonadReader r m) => MonadReader r (MCT m) where ask = lift ask {-# INLINE ask #-}- + local f (MCT g) = MCT $ \r -> do ma <- g r return $ local f ma {-# INLINE local #-} instance (MonadState s m) => MonadState s (MCT m) where- get = lift get + get = lift get {-# INLINE get #-}- + put = lift . put {-# INLINE put #-} instance (MonadWriter w m) => MonadWriter w (MCT m) where tell = lift . tell {-# INLINE tell #-}- + listen (MCT g) = MCT $ \r -> do ma <- g r return (listen ma) {-# INLINE listen #-}- + pass (MCT g) = MCT $ \r -> do maf <- g r return (pass maf)@@ -278,26 +297,64 @@ -------------------------- Random Number Distributions ---------------------- uniform :: Double -> Double -> MC Double-uniform 0 1 = MC $ \r -> GSL.getUniform r-uniform a b = MC $ \r -> getFlat r a b- +uniform 0 1 = liftRan0 GSL.getUniform+uniform a b = liftRan2 getFlat a b+ uniformInt :: Int -> MC Int-uniformInt n = MC $ \r -> GSL.getUniformInt r n+uniformInt = liftRan1 GSL.getUniformInt normal :: Double -> Double -> MC Double-normal 0 1 = MC $ \r -> getUGaussianRatioMethod r-normal mu 1 = MC $ \r -> liftM (mu +) (getUGaussianRatioMethod r)-normal 0 sigma = MC $ \r -> getGaussianRatioMethod r sigma-normal mu sigma = MC $ \r -> liftM (mu +) (getGaussianRatioMethod r sigma)+normal 0 1 = liftRan0 getUGaussianRatioMethod+normal mu 1 = (mu +) <$> liftRan0 getUGaussianRatioMethod+normal 0 sigma = liftRan1 getGaussianRatioMethod sigma+normal mu sigma = (mu +) <$> liftRan1 getGaussianRatioMethod sigma exponential :: Double -> MC Double-exponential mu = MC $ \r -> getExponential r mu+exponential = liftRan1 getExponential poisson :: Double -> MC Int-poisson mu = MC $ \r -> getPoisson r mu+poisson = liftRan1 getPoisson levy :: Double -> Double -> MC Double-levy c alpha = MC $ \r -> getLevy r c alpha+levy = liftRan2 getLevy levySkew :: Double -> Double -> Double -> MC Double-levySkew c alpha beta = MC $ \r -> getLevySkew r c alpha beta+levySkew = liftRan3 getLevySkew++cauchy :: Double -> MC Double+cauchy = liftRan1 getCauchy++beta :: Double -> Double -> MC Double+beta = liftRan2 getBeta++logistic :: Double -> MC Double+logistic = liftRan1 getLogistic++pareto :: Double -> Double -> MC Double+pareto = liftRan2 getPareto++weibull :: Double -> Double -> MC Double+weibull = liftRan2 getWeibull++gamma :: Double -> Double -> MC Double+gamma = liftRan2 getGamma++multinomial :: Int -> VS.Vector Double -> MC (VS.Vector Int)+multinomial = liftRan2 getMultinomial++dirichlet :: VS.Vector Double -> MC (VS.Vector Double)+dirichlet = liftRan1 getDirichlet++++liftRan0 :: (GSL.RNG -> IO a) -> MC a+liftRan0 = MC++liftRan1 :: (GSL.RNG -> a -> IO b) -> a -> MC b+liftRan1 f a = MC $ \r -> f r a++liftRan2 :: (GSL.RNG -> a -> b -> IO c) -> a -> b -> MC c+liftRan2 f a b = MC $ \r -> f r a b++liftRan3 :: (GSL.RNG -> a -> b -> c -> IO d) -> a -> b -> c -> MC d+liftRan3 f a b c = MC $ \r -> f r a b c
lib/Control/Monad/MC/Repeat.hs view
@@ -20,8 +20,8 @@ repeatMC :: (MonadMC m) => m a -> m [a] repeatMC = interleaveSequence . repeat {-# INLINE repeatMC #-}- --- | Produce a lazy list of the given length using the specified ++-- | Produce a lazy list of the given length using the specified -- generator. replicateMC :: (MonadMC m) => Int -> m a -> m [a] replicateMC n = interleaveSequence . replicate n
lib/Control/Monad/MC/Sample.hs view
@@ -13,13 +13,17 @@ sampleWithWeights, sampleSubset, sampleSubset',+ sampleSubsetWithWeights,+ sampleSubsetWithWeights', -- * Sampling @Int@s sampleInt, sampleIntWithWeights, sampleIntSubset, sampleIntSubset',- + sampleIntSubsetWithWeights,+ sampleIntSubsetWithWeights',+ -- * Shuffling shuffle, shuffleInt,@@ -29,7 +33,9 @@ import Control.Monad import Control.Monad.ST import Control.Monad.MC.Base+import Control.Monad.MC.Repeat import Control.Monad.MC.Walker+import Data.List( foldl', sort ) import Data.Vector.Unboxed( MVector, Unbox ) import qualified Data.Vector as BV@@ -54,23 +60,39 @@ in sampleHelp n xs $ sampleIntWithWeights ws n {-# INLINE sampleWithWeights #-} --- | @sampleSubset k xs@ samples a subset of size @k@ from @xs@ by --- sampling without replacement. The return value is a list of length @k@ +-- | @sampleSubset xs k@ samples a subset of size @k@ from @xs@ by+-- sampling without replacement. The return value is a list of length @k@ -- with the elements in the subset in the order that they were sampled. Note -- also that the elements are lazily generated.-sampleSubset :: (MonadMC m) => Int -> [a] -> m [a]-sampleSubset k xs = let+sampleSubset :: (MonadMC m) => [a] -> Int -> m [a]+sampleSubset xs k = let n = length xs- in sampleListHelp n xs $ sampleIntSubset k n+ in sampleListHelp n xs $ sampleIntSubset n k {-# INLINE sampleSubset #-} -- | Strict version of 'sampleSubset'.-sampleSubset' :: (MonadMC m) => Int -> [a] -> m [a]-sampleSubset' k xs = do- s <- sampleSubset k xs+sampleSubset' :: (MonadMC m) => [a] -> Int -> m [a]+sampleSubset' xs k = do+ s <- sampleSubset xs k length s `seq` return s {-# INLINE sampleSubset' #-} +-- | Sample a subset of the elements with the given weights. Return+-- the elements of the subset lazily in the order they were sampled.+sampleSubsetWithWeights :: (MonadMC m) => [(Double,a)] -> Int -> m [a]+sampleSubsetWithWeights wxs k = let+ (ws,xs) = unzip wxs+ n = length ws+ in sampleListHelp n xs $ sampleIntSubsetWithWeights ws n k+{-# INLINE sampleSubsetWithWeights #-}++-- | Strict version of 'sampleSubsetWithWeights'.+sampleSubsetWithWeights' :: (MonadMC m) => [(Double,a)] -> Int -> m [a]+sampleSubsetWithWeights' wxs k = do+ s <- sampleSubsetWithWeights wxs k+ length s `seq` return s+{-# INLINE sampleSubsetWithWeights' #-}+ sampleHelp :: (Monad m) => Int -> [a] -> m Int -> m a sampleHelp _n xs f = let arr = BV.fromList xs@@ -121,26 +143,26 @@ in liftM (indexTable qjs) (uniform 0 1) {-# INLINE sampleIntWithWeights #-} --- | @sampleIntSubset k n@ samples a subset of size @k@ by sampling without--- replacement from the integers @{ 0, ..., n-1 }@. The return value is a +-- | @sampleIntSubset n k@ samples a subset of size @k@ by sampling without+-- replacement from the integers @{ 0, ..., n-1 }@. The return value is a -- list of length @k@ with the elements in the subset in the order that they -- were sampled. Note also that the elements are lazily generated. sampleIntSubset :: (MonadMC m) => Int -> Int -> m [Int]-sampleIntSubset k n | k < 0 = fail "negative subset size"+sampleIntSubset n k | k < 0 = fail "negative subset size" | k > n = fail "subset size is too big" | otherwise = do- us <- randomIndices k n+ us <- randomIndices n k return $ runST $ do ints <- MV.new n :: ST s (MVector s Int) sequence_ [ MV.unsafeWrite ints i i | i <- [0 .. n-1] ] sampleIntSubsetHelp ints us (n-1) where- randomIndices k' n' | k' == 0 = return []+ randomIndices n' k' | k' == 0 = return [] | otherwise = unsafeInterleaveMC $ do u <- uniformInt n'- us <- randomIndices (k'-1) (n'-1)+ us <- randomIndices (n'-1) (k'-1) return (u:us)- + sampleIntSubsetHelp _ [] _ = return [] sampleIntSubsetHelp ints (u:us) n' = unsafeInterleaveST $ do i <- MV.unsafeRead ints u@@ -151,11 +173,63 @@ -- | Strict version of 'sampleIntSubset'. sampleIntSubset' :: (MonadMC m) => Int -> Int -> m [Int]-sampleIntSubset' k n = do- s <- sampleIntSubset k n+sampleIntSubset' n k = do+ s <- sampleIntSubset n k length s `seq` return s {-# INLINE sampleIntSubset' #-} +-- | @sampleIntSubsetWithWeights ws n k@ samplea size @k@ subset of+-- @{ 0, ..., n-1 }@ with the given weights by sampling elements without+-- replacement. It returns the elements of the subset lazily in the order+-- they were sampled.+sampleIntSubsetWithWeights :: (MonadMC m) => [Double] -> Int -> Int -> m [Int]+sampleIntSubsetWithWeights ws n k = let+ w_sum0 = foldl' (+) 0 $ take n ws+ wjs = [ (w / w_sum0, j) | (w,j) <- reverse $ sort $ zip ws [ 0..n-1 ] ]+ in do+ us <- replicateMC k $ uniform 0 1+ return $ runST $ do+ ints <- MV.new n :: ST s (MVector s (Double,Int))+ sequence_ [ MV.unsafeWrite ints i wj | (i,wj) <- zip [ 0.. ] wjs ]+ go ints n 1 us+ where+ go ints n' w_sum us | null us = return []+ | otherwise = let+ target = head us * w_sum+ in unsafeInterleaveST $ do+ (i,(w,j)) <- findTarget ints n' target 0 0+ shiftDown ints (i+1) (n'-1)+ let w_sum' = w_sum - w+ n'' = n' - 1+ us' = tail us+ js <- go ints n'' w_sum' us'+ return $ j:js++ findTarget ints n' target i acc+ | i == n' - 1 = do+ wj <- MV.unsafeRead ints i+ return (i,wj)+ | otherwise = do+ (w,j) <- MV.unsafeRead ints i+ let acc' = acc + w+ if target <= acc'+ then return (i,(w,j))+ else findTarget ints n' target (i+1) acc'++ shiftDown ints from to =+ forM_ [ from..to ] $ \i -> do+ wj <- MV.unsafeRead ints i+ MV.unsafeWrite ints (i-1) wj++{-# INLINE sampleIntSubsetWithWeights #-}++-- | Strict version of 'sampleIntSubsetWithWeights'.+sampleIntSubsetWithWeights' :: (MonadMC m) => [Double] -> Int -> Int -> m [Int]+sampleIntSubsetWithWeights' ws n k = do+ s <- sampleIntSubsetWithWeights ws n k+ length s `seq` return s+{-# INLINE sampleIntSubsetWithWeights' #-}+ -- | @shuffle xs@ randomly permutes the list @xs@ and returns -- the result. All permutations of the elements of @xs@ are equally -- likely.@@ -191,7 +265,7 @@ y <- MV.unsafeRead marr j MV.unsafeWrite marr i y MV.unsafeWrite marr j x-{-# INLINE shuffleU #-} +{-# INLINE shuffleU #-} {-# RULES "shuffle/Double" forall xs. shuffle (xs :: [Double]) = shuffleU xs #-}@@ -200,7 +274,7 @@ -- | @shuffleInt n@ generates a sequence of swaps equivalent to a--- uniformly-chosen random permutatation of the integers @{0, ..., n-1}@. +-- uniformly-chosen random permutatation of the integers @{0, ..., n-1}@. -- For an input of @n@, there are @n-1@ swaps, which are lazily generated. shuffleInt :: (MonadMC m) => Int -> m [(Int,Int)] shuffleInt n =
lib/Data/Summary/Bool.hs view
@@ -14,7 +14,7 @@ Summary, summary, update,- + -- * @Summary@ properties sampleSize, count,@@ -39,7 +39,7 @@ {-# UNPACK #-} !Int -- number of successes instance Show Summary where- show s@(S n c) = + show s@(S n c) = printf " sample size: %d" n ++ printf "\n successes: %g" c ++ printf "\n proportion: %g" (sampleMean s)@@ -50,12 +50,12 @@ -- | Get a summary of a list of values. summary :: [Bool] -> Summary summary = foldl' update empty- + -- | Get an empty summary. empty :: Summary empty = S 0 0 --- | Update the summary with a data point. +-- | Update the summary with a data point. update :: Summary -> Bool -> Summary update (S n c) i = let n' = n+1
lib/Data/Summary/Double.hs view
@@ -14,7 +14,7 @@ Summary, summary, update,- + -- * @Summary@ properties sampleSize, sampleMin,@@ -42,7 +42,7 @@ {-# UNPACK #-} !Double -- sample max instance Show Summary where- show s@(S n mu _ l h) = + show s@(S n mu _ l h) = printf " sample size: %d" n ++ printf "\n min: %g" l ++ printf "\n max: %g" h@@ -54,13 +54,13 @@ -- | Get a summary of a list of values. summary :: [Double] -> Summary summary = foldl' update empty- + -- | Get an empty summary. empty :: Summary empty = S 0 0 0 (1/0) (-1/0) --- | Update the summary with a data point. --- Running mean and variance computed as in Knuth, Vol 2, page 232, +-- | Update the summary with a data point.+-- Running mean and variance computed as in Knuth, Vol 2, page 232, -- 3rd edition, see http://www.johndcook.com/standard_deviation.html for -- a description. update :: Summary -> Double -> Summary
lib/Data/Summary/Utils.hs view
@@ -23,7 +23,7 @@ -> Double -- ^ the sample mean -> Double -- ^ the sample standard error -> (Double,Double)-interval level xbar se | not (level > 0 && level < 1) = +interval level xbar se | not (level > 0 && level < 1) = error "level must be between 0 and 1" | otherwise = let alpha = (0.5 - level) + 0.5
monte-carlo.cabal view
@@ -1,5 +1,5 @@ name: monte-carlo-version: 0.3.1+version: 0.4 license: BSD3 license-file: LICENSE author: Patrick Perry@@ -7,8 +7,8 @@ homepage: http://github.com/patperry/hs-monte-carlo category: Math synopsis: A monad and transformer for Monte Carlo calculations.-description: A monad and transformer for Monte Carlo calculations. The - monads carry and provide access to a random number generator. +description: A monad and transformer for Monte Carlo calculations. The+ monads carry and provide access to a random number generator. Importantly, they only keep one copy of the generator state, and so are much more efficient than MonadRandom. Currently, only the generator that comes with the GNU Scientific Library@@ -21,7 +21,7 @@ tests/Makefile library- exposed-modules: + exposed-modules: Control.Monad.MC Control.Monad.MC.Class Control.Monad.MC.GSL@@ -29,24 +29,24 @@ Data.Summary.Bool Data.Summary.Double Data.Summary.Utils- + other-modules: Control.Monad.MC.Base Control.Monad.MC.GSLBase Control.Monad.MC.Repeat Control.Monad.MC.Sample Control.Monad.MC.Walker- + extensions: FlexibleInstances, MultiParamTypeClasses, TypeFamilies, UndecidableInstances - build-depends: base >= 4 && < 5,- gsl-random >= 0.3.1,- mtl >= 1.1 && < 1.2,- vector >= 0.6 && < 0.8+ build-depends: base >= 4 && < 5,+ gsl-random >= 0.4.3 && < 0.5,+ mtl >= 1.1 && < 1.2,+ vector >= 0.6 && < 0.8 hs-source-dirs: lib ghc-options: -Wall