module Numeric.GSL.Distribution.Continuous (
ZeroParamDist(..), OneParamDist(..)
, TwoParamDist(..), ThreeParamDist(..)
, MultiParamDist(..)
, BivariateDist(..)
, DistFunc(..)
, random_0p, density_0p
, random_1p, density_1p
, random_2p, density_2p
, random_3p, density_3p
, random_mp, density_mp
, random_biv, density_biv
, spherical_vector
) where
import Data.Packed.Vector
import Data.Packed.Development
import Control.Monad(when)
import Foreign hiding(shift)
import Foreign.ForeignPtr
import Foreign.C.Types(CInt,CChar)
import Foreign.C.String(newCString,peekCString)
import Numeric.GSL.Distribution.Common
data ZeroParamDist = Landau
deriving Enum
data OneParamDist = Gaussian
| Exponential
| Laplace
| Cauchy
| Rayleigh
| ChiSq
| TDist
| Logistic
deriving Enum
data TwoParamDist = GaussianTail
| ExpPower
| RayleighTail
| Levy
| Gamma
| Uniform
| Lognormal
| FDist
| Beta
| Pareto
| Weibull
| GumbellI
| GumbellII
deriving Enum
data ThreeParamDist = LevySkew
deriving Enum
data MultiParamDist = Dirichlet
deriving Enum
data BivariateDist = BiGaussian
deriving Enum
fromei x = fromIntegral (fromEnum x) :: CInt
random_0p :: ZeroParamDist
-> Int
-> Double
random_0p d s = unsafePerformIO $ distribution_random_zero_param (fromIntegral s) (fromei d)
density_0p :: ZeroParamDist
-> DistFunc
-> Double
-> Double
density_0p d f x = unsafePerformIO $ do
case d of
Landau -> density_only f d x
where density_only f' d' x' = if f' /= Density
then error "distribution has no CDF"
else distribution_dist_zero_param (fromei f') (fromei d') x'
foreign import ccall "distribution-aux.h random0" distribution_random_zero_param :: CInt -> CInt -> IO Double
foreign import ccall "distribution-aux.h random0_dist" distribution_dist_zero_param :: CInt -> CInt -> Double -> IO Double
random_1p :: OneParamDist
-> Int
-> Double
-> Double
random_1p d s p = unsafePerformIO $
alloca $ \r -> do
check "random1p" $ distribution_random_one_param (fromIntegral s) (fromei d) p r
r' <- peek r
return r'
density_1p :: OneParamDist
-> DistFunc
-> Double
-> Double
-> Double
density_1p d f p x = unsafePerformIO $ distribution_dist_one_param (fromei f) (fromei d) x p
foreign import ccall "distribution-aux.h random1" distribution_random_one_param :: CInt -> CInt -> Double -> Ptr Double -> IO CInt
foreign import ccall "distribution-aux.h random1_dist" distribution_dist_one_param :: CInt -> CInt -> Double -> Double -> IO Double
random_2p :: TwoParamDist
-> Int
-> Double
-> Double
-> Double
random_2p d s p1 p2 = unsafePerformIO $
alloca $ \r -> do
check "random2p" $ distribution_random_two_param (fromIntegral s) (fromei d) p1 p2 r
r' <- peek r
return r'
density_2p :: TwoParamDist
-> DistFunc
-> Double
-> Double
-> Double
-> Double
density_2p d f p1 p2 x = unsafePerformIO $ do
case d of
GaussianTail -> density_only f d p1 p2 x
ExpPower -> no_inverse f d p1 p2 x
RayleighTail -> density_only f d p1 p2 x
Levy -> error "no PDF or CDF for Levy"
_ -> distribution_dist_two_param (fromei f) (fromei d) x p1 p2
where density_only f' d' p1' p2' x' = if f' /= Density
then error "distribution has no CDF"
else distribution_dist_two_param (fromei f') (fromei d') x' p1' p2'
no_inverse f' d' p1' p2' x' = if (f' == LowInv || f' == UppInv)
then error "distribution has no inverse CDF"
else distribution_dist_two_param (fromei f') (fromei d') x' p1' p2'
foreign import ccall "distribution-aux.h random2" distribution_random_two_param :: CInt -> CInt -> Double -> Double -> Ptr Double -> IO CInt
foreign import ccall "distribution-aux.h random2_dist" distribution_dist_two_param :: CInt -> CInt -> Double -> Double -> Double -> IO Double
random_3p :: ThreeParamDist
-> Int
-> Double
-> Double
-> Double
-> Double
random_3p d s p1 p2 p3 = unsafePerformIO $
alloca $ \r -> do
check "random_3p" $ distribution_random_three_param (fromIntegral s) (fromei d) p1 p2 p3 r
r' <- peek r
return r'
density_3p :: ThreeParamDist
-> DistFunc
-> Double
-> Double
-> Double
-> Double
-> Double
density_3p d f p1 p2 p3 x = unsafePerformIO $ do
case d of
LevySkew -> error "Levy skew has no PDF or CDF"
where density_only f' d' p1' p2' p3' x' = if f' /= Density
then error "distribution has no CDF"
else distribution_dist_three_param (fromei f') (fromei d') x' p1' p2' p3'
foreign import ccall "distribution-aux.h random3" distribution_random_three_param :: CInt -> CInt -> Double -> Double -> Double -> Ptr Double -> IO CInt
foreign import ccall "distribution-aux.h random3_dist" distribution_dist_three_param :: CInt -> CInt -> Double -> Double -> Double -> Double -> IO Double
random_mp :: MultiParamDist
-> Int
-> Vector Double
-> Vector Double
random_mp d s p = unsafePerformIO $ do
r <- createVector $ dim p
app2 (distribution_random_multi_param (fromIntegral s) (fromei d)) vec p vec r "random_mp"
return r
density_mp :: MultiParamDist
-> DistFunc
-> Vector Double
-> Vector Double
-> Double
density_mp d f p q = unsafePerformIO $ do
case d of
Dirichlet -> density_only f d p q
where density_only f' d' p' q' = if f' /= Density
then error "distribution has no CDF"
else alloca $ \r -> do
app2 (distribution_dist_multi_param (fromei f') (fromei d') r) vec p vec q "density_mp"
r' <- peek r
return r'
foreign import ccall "distribution-aux.h random_mp" distribution_random_multi_param :: CInt -> CInt -> CInt -> Ptr Double -> CInt -> Ptr Double -> IO CInt
foreign import ccall "distribution-aux.h random_mm_dist" distribution_dist_multi_param :: CInt -> CInt -> Ptr Double -> CInt -> Ptr Double -> CInt -> Ptr Double -> IO CInt
random_biv :: BivariateDist
-> Int
-> Double
-> Double
-> Double
-> (Double,Double)
random_biv d s p1 p2 p3 = unsafePerformIO $
alloca $ \r1 ->
alloca $ \r2 -> do
distribution_random_bivariate (fromIntegral s) (fromei d) p1 p2 p3 r1 r2
r1' <- peek r1
r2' <- peek r2
return (r1',r2')
density_biv :: BivariateDist
-> DistFunc
-> Double
-> Double
-> Double
-> (Double,Double)
-> Double
density_biv d f p1 p2 p3 (x,y) = unsafePerformIO $ do
case d of
BiGaussian -> density_only f d p1 p2 p3 x y
where density_only f' d' p1' p2' p3' x' y' = if f' /= Density
then error "distribution has no CDF"
else distribution_dist_bivariate (fromei f') (fromei d') x' y' p1' p2' p3'
foreign import ccall "distribution-aux.h random_biv" distribution_random_bivariate :: CInt -> CInt -> Double -> Double -> Double -> Ptr Double -> Ptr Double -> IO ()
foreign import ccall "distribution-aux.h random_biv_dist" distribution_dist_bivariate :: CInt -> CInt -> Double -> Double -> Double -> Double -> Double -> IO Double
spherical_vector :: Int
-> Int
-> Vector Double
spherical_vector s vs = unsafePerformIO $ do
r <- createVector vs
app1 (distribution_spherical_vector (fromIntegral s)) vec r "spherical_vector"
return r
foreign import ccall "distribution-aux.h random_vector" distribution_spherical_vector :: CInt -> CInt -> Ptr Double -> IO CInt