normaldistribution (empty) → 1.0
raw patch · 5 files changed
+246/−0 lines, 5 filesdep +basedep +haskell98setup-changed
Dependencies added: base, haskell98
Files
- Data/Random/Normal.hs +157/−0
- LICENSE +31/−0
- README +1/−0
- Setup.lhs +3/−0
- normaldistribution.cabal +54/−0
+ Data/Random/Normal.hs view
@@ -0,0 +1,157 @@+{- |+ Copyright : Copyright (C) 2011 Bjorn Buckwalter+ License : BSD3++ Maintainer : bjorn.buckwalter@gmail.com+ Stability : Stable+ Portability: Haskell 98++This purpose of this library is to have a simple API and no+dependencies beyond Haskell 98 in order to let you produce normally+distributed random values with a minimum of fuss. This library does+/not/ attempt to be blazingly fast nor to pass stringent tests of+randomness. It attempts to be very easy to install and use while+being \"good enough\" for many applications (simulations, games, etc.).+The API builds upon and is largely analogous to that of the Haskell+98 @Random@ module (more recently @System.Random@).++Pure:++> (sample,g) = normal myRandomGen -- using a Random.RandomGen+> samples = normals myRandomGen -- infinite list+> samples2 = mkNormals 10831452 -- infinite list using a seed++In the IO monad:++> sample <- normalIO+> samples <- normalsIO -- infinite list++With custom mean and standard deviation:++> (sample,g) = normal' (mean,sigma) myRandomGen+> samples = normals' (mean,sigma) myRandomGen+> samples2 = mkNormals' (mean,sigma) 10831452++> sample <- normalIO' (mean,sigma)+> samples <- normalsIO' (mean,sigma)++Internally the library uses the Central Limit Theorem to approximate+normally distributed values from multiple uniformly distributed+random values.++-}+++module Data.Random.Normal (+ -- * Pure interface+ normal+ , normals+ , mkNormals++ -- ** Custom mean and standard deviation+ , normal'+ , normals'+ , mkNormals'++ -- * Using the global random number generator+ , normalIO+ , normalsIO++ -- ** Custom mean and standard deviation+ , normalIO'+ , normalsIO'++ ) where++import List (mapAccumL) -- Data.List+import Random -- System.Random+++-- Normal distribution approximation+-- ---------------------------------+-- | Central limit theorem for approximating normally distributed+-- sampling. Takes a list of no less than twelve random uniformly+-- distributed samples in the range [0,1] and uses the first twelve+-- samples to approximate a normally distributed random sample with+-- mean 0 and standard deviation 1.+centralLimitTheorem :: Fractional a => [a] -> a+centralLimitTheorem ss = sum (take 12 ss) - 6+++-- API+-- ===+-- | Takes a random number generator g, and returns a random value+-- normally distributed with mean 0 and standard deviation 1,+-- together with a new generator. This function is ananalogous to+-- 'Random.random'.+normal :: (RandomGen g, Random a, Fractional a) => g -> (a,g)+normal g = (centralLimitTheorem as, g')+ -- While The Haskell 98 report says "For fractional types, the+ -- range is normally the semi-closed interval [0,1)" we will+ -- specify the range explicitely just to be sure.+ where (g',as) = iterateN 12 (swap . randomR (0,1)) g++-- | Plural variant of 'normal', producing an infinite list of+-- random values instead of returning a new generator. This function+-- is ananalogous to 'Random.randoms'.+normals :: (RandomGen g, Random a, Fractional a) => g -> [a]+normals g = x:normals g' where (x,g') = normal g++-- | Creates a infinite list of normally distributed random values+-- from the provided random generator seed. (In the implementation+-- the seed is fed to 'Random.mkStdGen' to produce the random+-- number generator.)+mkNormals :: (Random a, Fractional a) => Int -> [a]+mkNormals = normals . mkStdGen+++-- | A variant of 'normal' that uses the global random number+-- generator. This function is analogous to 'Random.randomIO'.+normalIO :: (Random a, Fractional a) => IO a+normalIO = fmap centralLimitTheorem $ mapM randomRIO $ repeat (0,1)++-- | Creates a infinite list of normally distributed random values+-- using the global random number generator. (In the implementation+-- 'Random.newStdGen' is used.)+normalsIO :: (Random a, Fractional a) => IO [a]+normalsIO = fmap normals newStdGen+++-- With mean and standard deviation+-- --------------------------------+-- | Analogous to 'normal' but uses the supplied (mean, standard+-- deviation).+normal' :: (RandomGen g, Random a, Fractional a) => (a,a) -> g -> (a,g)+normal' (mean, sigma) g = (x * sigma + mean, g') where (x, g') = normal g++-- | Analogous to 'normals' but uses the supplied (mean, standard+-- deviation).+normals' :: (RandomGen g, Random a, Fractional a) => (a,a) -> g -> [a]+normals' (mean, sigma) g = map (\x -> x * sigma + mean) (normals g)++-- | Analogous to 'mkNormals' but uses the supplied (mean, standard+-- deviation).+mkNormals' :: (Random a, Fractional a) => (a,a) -> Int -> [a]+mkNormals' ms= normals' ms . mkStdGen+++-- | Analogous to 'normalIO' but uses the supplied (mean, standard+-- deviation).+normalIO' ::(Random a, Fractional a) => (a,a) -> IO a+normalIO' (mean,sigma) = fmap (\x -> x * sigma + mean) normalIO++-- | Analogous to 'normalsIO' but uses the supplied (mean, standard+-- deviation).+normalsIO' :: (Random a, Fractional a) => (a,a) -> IO [a]+normalsIO' ms = fmap (normals' ms) newStdGen+++-- Helpers+-- -------+-- | Swap the elements in a tuple.+swap :: (a,b) -> (b,a)+swap (x,y) = (y,x)++-- | Iterate on the accumulator a specified number of times.+iterateN :: Int -> (acc -> (acc, x)) -> acc -> (acc, [x])+iterateN n f a0 = mapAccumL (\a _ -> f a) a0 [1..n]
+ LICENSE view
@@ -0,0 +1,31 @@+Copyright (c) 2011, Bjorn Buckwalter.+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 the copyright holder(s) nor the names of+ 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.
+ README view
@@ -0,0 +1,1 @@+See normaldistribution.cabal for information.
+ Setup.lhs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ normaldistribution.cabal view
@@ -0,0 +1,54 @@+Name: normaldistribution+Version: 1.0+License: BSD3+License-File: LICENSE+Copyright: Bjorn Buckwalter 2011+Author: Bjorn Buckwalter +Maintainer: bjorn.buckwalter@gmail.com+Stability: Stable+Homepage: https://github.com/bjornbm/normaldistribution+Synopsis:++ Minimum fuss normally distributed random values.++Description:++ This purpose of this library is to have a simple API and no+ dependencies beyond Haskell 98 in order to let you produce+ normally distributed random values with a minimum of fuss. This+ library does /not/ attempt to be blazingly fast nor to pass+ stringent tests of randomness. It attempts to be very easy to+ install and use while being \"good enough\" for many applications+ (simulations, games, etc.). The API builds upon and is largely+ analogous to that of the Haskell 98 @Random@ module (more+ recently @System.Random@).+ .+ Pure:+ .+ > (sample,g) = normal myRandomGen -- using a Random.RandomGen+ > samples = normals myRandomGen -- infinite list+ > samples2 = mkNormals 10831452 -- infinite list using a seed+ .+ In the IO monad:+ .+ > sample <- normalIO+ > samples <- normalsIO -- infinite list+ .+ With custom mean and standard deviation:+ .+ > (sample,g) = normal' (mean,sigma) myRandomGen+ > samples = normals' (mean,sigma) myRandomGen+ > samples2 = mkNormals' (mean,sigma) 10831452+ .+ > sample <- normalIO' (mean,sigma)+ > samples <- normalsIO' (mean,sigma)+ .+ Internally the library uses the Central Limit Theorem to+ approximate normally distributed values from multiple uniformly+ distributed random values.++Category: Math, Statistics+Build-Type: Simple+Build-Depends: base < 5, haskell98 < 1.1+Exposed-Modules: Data.Random.Normal+Extra-source-files: README, LICENSE