gsl-random (empty) → 0.1
raw patch · 7 files changed
+388/−0 lines, 7 filesdep +basesetup-changed
Dependencies added: base
Files
- GSL/Random/Dist.hs +58/−0
- GSL/Random/Gen.hs +14/−0
- GSL/Random/Gen/Internal.hs +245/−0
- LICENSE +30/−0
- README +3/−0
- Setup.lhs +6/−0
- gsl-random.cabal +32/−0
+ GSL/Random/Dist.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE ForeignFunctionInterface #-}+-----------------------------------------------------------------------------+-- |+-- Module : GSL.Random.Dist+-- Copyright : Copyright (c) , Patrick Perry <patperry@stanford.edu>+-- License : BSD3+-- Maintainer : Patrick Perry <patperry@stanford.edu>+-- Stability : experimental+--++module GSL.Random.Dist (+ getPoisson,+ getFlat,+ getGaussian,+ ) where++import Foreign.C.Types ( CUInt, CDouble )+import Foreign.ForeignPtr ( withForeignPtr )+import Foreign.Ptr ( Ptr )++import GSL.Random.Gen.Internal ( RNG(..) )++-- | @getPoisson r mu@ gets a poisson random variable with mean @mu@.+getPoisson :: RNG -> Double -> IO Int+getPoisson (MkRNG fptr) mu =+ let mu' = realToFrac mu+ in withForeignPtr fptr $ \ptr -> do+ x <- gsl_ran_poisson ptr mu' + return $ (fromInteger . toInteger) x+ +foreign import ccall unsafe "gsl/gsl_randist.h"+ gsl_ran_poisson :: Ptr () -> CDouble -> IO CUInt++-- | @getFlat r a b@ gets a value uniformly chosen in @[a,b)@.+getFlat :: RNG -> Double -> Double -> IO (Double)+getFlat (MkRNG fptr) a b =+ let a' = realToFrac a+ b' = realToFrac b+ in withForeignPtr fptr $ \ptr -> do+ x <- gsl_ran_flat ptr a' b'+ return $ realToFrac x+ +foreign import ccall unsafe "gsl/gsl_randist.h"+ gsl_ran_flat :: Ptr () -> CDouble -> CDouble -> IO CDouble+++-- | @getGaussian r sigma@ gets a normal random variable with mean+-- @0@ and standard deviation @sigma@.+getGaussian :: RNG -> Double -> IO Double+getGaussian (MkRNG fptr) sigma =+ let sigma' = realToFrac sigma+ in withForeignPtr fptr $ \ptr -> do+ x <- gsl_ran_gaussian ptr sigma'+ return $ realToFrac x+ +foreign import ccall unsafe "gsl/gsl_randist.h"+ gsl_ran_gaussian :: Ptr () -> CDouble -> IO CDouble+
+ GSL/Random/Gen.hs view
@@ -0,0 +1,14 @@+-----------------------------------------------------------------------------+-- |+-- Module : GSL.Random.Gen+-- Copyright : Copyright (c) , Patrick Perry <patperry@stanford.edu>+-- License : BSD3+-- Maintainer : Patrick Perry <patperry@stanford.edu>+-- Stability : experimental+--++module GSL.Random.Gen (+ module GSL.Random.Gen.Internal+ ) where++import GSL.Random.Gen.Internal hiding ( MkRNG )
+ GSL/Random/Gen/Internal.hs view
@@ -0,0 +1,245 @@+{-# LANGUAGE ForeignFunctionInterface #-}+-----------------------------------------------------------------------------+-- |+-- Module : GSL.Random.Gen.Internal+-- Copyright : Copyright (c) , Patrick Perry <patperry@stanford.edu>+-- License : BSD3+-- Maintainer : Patrick Perry <patperry@stanford.edu>+-- Stability : experimental+--++module GSL.Random.Gen.Internal (+ -- * Data types+ RNG(..),+ RNGType,+ + -- * Initializing+ newRNG,+ setSeed,+ + -- * Sampling+ getSample,+ getUniform,+ getUniformPos,+ getUniformInt,+ + -- * Auxiliary functions+ getName,+ getMax,+ getMin,+ getSize,+ getState,+ setState,+ + -- * Copying state+ copyRNG,+ cloneRNG,++ -- * Algorithms+ mt19937,+ + ) where+ +import Control.Monad ( liftM )+import Data.Maybe ( fromJust ) +import Data.Word ( Word8, Word64 )+import Foreign.C.Types ( CULong, CSize, CInt, CDouble )+import Foreign.C.String ( CString, withCAString, peekCAString )+import Foreign.ForeignPtr ( ForeignPtr, newForeignPtr, withForeignPtr )+import Foreign.Marshal.Array ( peekArray, pokeArray, advancePtr )+import Foreign.Ptr ( Ptr, FunPtr, castPtr, nullPtr )+import Foreign.Storable ( peek )+import System.IO.Unsafe ( unsafePerformIO )++newtype RNG = MkRNG (ForeignPtr ())+newtype RNGType = MkRNGType (Ptr ())+++--------------------------- Initialization ----------------------------------++-- | Allocate a new random number generator of the given type and initialize+-- it with the default seed.+newRNG :: RNGType -> IO RNG+newRNG t = do+ ptr <- gsl_rng_alloc t+ fptr <- newForeignPtr p_gsl_rng_free ptr+ return $! MkRNG fptr++foreign import ccall unsafe "gsl/gsl_rng.h"+ gsl_rng_alloc :: RNGType -> IO (Ptr ())++foreign import ccall unsafe "gsl/gsl_rng.h &gsl_rng_free"+ p_gsl_rng_free :: FunPtr (Ptr () -> IO ())++-- | Seed the generator with the given value.+setSeed :: RNG -> Word64 -> IO ()+setSeed (MkRNG fptr) seed =+ let seed' = (fromInteger . toInteger) seed+ in withForeignPtr fptr $ flip gsl_rng_set seed'++foreign import ccall unsafe "gsl/gsl_rng.h"+ gsl_rng_set :: Ptr () -> CULong -> IO ()+ ++--------------------------- Sampling ----------------------------------------++-- | Returns a value uniform in [rngMin, rngMax]+getSample :: RNG -> IO Word64+getSample (MkRNG fptr) =+ withForeignPtr fptr $ \ptr ->+ gsl_rng_get ptr >>= return . fromInteger . toInteger+ +foreign import ccall unsafe "gsl/gsl_rng.h"+ gsl_rng_get :: Ptr () -> IO CULong++-- | Returns a value uniform on [0,1)+getUniform :: RNG -> IO Double+getUniform (MkRNG fptr) =+ withForeignPtr fptr $ \ptr ->+ gsl_rng_uniform ptr >>= return . realToFrac+ +foreign import ccall unsafe "gsl/gsl_rng.h"+ gsl_rng_uniform :: Ptr () -> IO CDouble++-- | Returns a value uniform on (0,1)+getUniformPos :: RNG -> IO Double+getUniformPos (MkRNG fptr) =+ withForeignPtr fptr $ \ptr ->+ gsl_rng_uniform_pos ptr >>= return . realToFrac++foreign import ccall unsafe "gsl/gsl_rng.h"+ gsl_rng_uniform_pos :: Ptr () -> IO CDouble++-- | Returns an integer uniform on [0,n-1]. @n@ must be greater than @0@.+getUniformInt :: RNG -> Int -> IO Int+getUniformInt (MkRNG fptr) n + | n <= 0 =+ ioError $ userError $ + "rngUnifInt: expected \"n\" to be greater than 0" +++ " but got `" ++ show n ++ "' instead."+ | otherwise =+ let n' = (fromInteger . toInteger) n+ in withForeignPtr fptr $ \ptr ->+ gsl_rng_uniform_int ptr n' >>= return . fromInteger . toInteger+ +foreign import ccall unsafe "gsl/gsl_rng.h"+ gsl_rng_uniform_int :: Ptr () -> CULong -> IO CULong+++--------------------------- Auxiliary Functions -----------------------------++-- | Get the name of the generator.+getName :: RNG -> IO String+getName (MkRNG fptr) =+ withForeignPtr fptr $ \ptr ->+ peekCAString (gsl_rng_name ptr)+ +foreign import ccall unsafe "gsl/gsl_rng.h"+ gsl_rng_name :: Ptr () -> CString++-- | Get the largest value that the generator can return.+getMax :: RNG -> IO Word64+getMax (MkRNG fptr) =+ withForeignPtr fptr $ \ptr ->+ (return . fromInteger . toInteger) (gsl_rng_max ptr)+ +foreign import ccall unsafe "gsl/gsl_rng.h"+ gsl_rng_max :: Ptr () -> CULong++-- | Get the smallest value that the generator can return.+getMin :: RNG -> IO Word64+getMin (MkRNG fptr) =+ withForeignPtr fptr $ \ptr ->+ (return . fromInteger . toInteger) (gsl_rng_min ptr)+ +foreign import ccall unsafe "gsl/gsl_rng.h"+ gsl_rng_min :: Ptr () -> CULong++-- | Get the size of the generator state, in bytes.+getSize :: RNG -> IO Word64+getSize (MkRNG fptr) =+ withForeignPtr fptr $ \ptr ->+ (return . fromInteger . toInteger) (gsl_rng_size ptr)++foreign import ccall unsafe "gsl/gsl_rng.h"+ gsl_rng_size :: Ptr () -> CSize++-- | Get the generator state.+getState :: RNG -> IO [Word8]+getState rng@(MkRNG fptr) = do+ n <- liftM (fromInteger . toInteger) (getSize rng)+ withForeignPtr fptr $ \ptr ->+ peekArray n (gsl_rng_state ptr)+ +foreign import ccall unsafe "gsl/gsl_randist.h"+ gsl_rng_state :: Ptr () -> Ptr Word8++-- | Set the generator state. The input array should have size equal+-- to @getSize@ of the generator; otherwise, strange things will happen.+setState :: RNG -> [Word8] -> IO ()+setState (MkRNG fptr) state = do+ withForeignPtr fptr $ \ptr ->+ pokeArray (gsl_rng_state ptr) state++--------------------------- Copying State -----------------------------------++-- | @copyRNG dst src@ copies the state from one generator to another. The+-- two generators must have the same type.+copyRNG :: RNG -> RNG -> IO ()+copyRNG (MkRNG fdst) (MkRNG fsrc) =+ withForeignPtr fdst $ \dst ->+ withForeignPtr fsrc $ \src ->+ gsl_rng_memcpy dst src+ +foreign import ccall unsafe "gsl/gsl_rng.h"+ gsl_rng_memcpy :: Ptr () -> Ptr () -> IO ()++-- | Allocate a new random number generator that is an exact copy of another+-- generator+cloneRNG :: RNG -> IO RNG+cloneRNG (MkRNG fptr) =+ withForeignPtr fptr $ \ptr -> do+ ptr' <- gsl_rng_clone ptr+ fptr' <- newForeignPtr p_gsl_rng_free ptr'+ ptr' `seq` return $! MkRNG fptr'++foreign import ccall unsafe "gsl/gsl_rng.h"+ gsl_rng_clone :: Ptr () -> IO (Ptr ())+++--------------------------- Algorithms --------------------------------------+++mt19937 :: RNGType+mt19937 = + unsafePerformIO $+ withCAString "mt19937" $ \name ->+ liftM fromJust $ getRngType name+{-# NOINLINE mt19937 #-}++getRngType :: CString -> IO (Maybe RNGType)+getRngType name =+ go gsl_rng_types_setup+ where+ go :: Ptr (Ptr ()) -> IO (Maybe RNGType)+ go types = do+ t <- peek types+ if t == nullPtr + then+ return Nothing+ + else do+ name' <- peek (castPtr t)+ cmp <- c_strcmp name name'+ + if cmp == 0+ then return $ Just (MkRNGType t)+ else go $ types `advancePtr` 1+ +++foreign import ccall unsafe "string.h strcmp"+ c_strcmp :: CString -> CString -> IO CInt++foreign import ccall unsafe "gsl/gsl_randist.h"+ gsl_rng_types_setup :: Ptr (Ptr ())
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) Patrick Perry <patperry@stanford.edu> 2008++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++1. Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++2. 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.++3. Neither the name of the author nor the names of his contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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,3 @@+You may need to edit the cabal file to get the right libraries linked in. In+particular, you may need to change "cblas" to "gslcblas". Or, if you are using+ATLAS, you may need to add atlas at the end of the library list.
+ Setup.lhs view
@@ -0,0 +1,6 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> import System.Cmd+>+> main = defaultMain+>
+ gsl-random.cabal view
@@ -0,0 +1,32 @@+name: gsl-random+version: 0.1+homepage: http://stat.stanford.edu/~patperry/code/gsl-random+synopsis: Bindings the the GSL random number generation facilities.+description:+ Bindings to the GNU Scientific Library random number generators and random+ distributions.+ .+category: Math+license: BSD3+license-file: LICENSE+copyright: (c) 2008. Patrick Perry <patperry@stanford.edu>+author: Patrick Perry+maintainer: Patrick Perry <patperry@stanford.edu>+cabal-version: >= 1.2.0+build-type: Simple+tested-with: GHC ==6.8.3++extra-source-files: README++library+ exposed-modules: GSL.Random.Gen+ GSL.Random.Dist+ other-modules: GSL.Random.Gen.Internal++ ghc-options: -Wall+ extensions: ForeignFunctionInterface+ build-depends: base++ extra-libraries: gsl cblas+ extra-lib-dirs: /opt/local/lib+