1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
module Probability.Distribution.Uniform where
import Probability.Random
import MCMC
foreign import bpcall "Distribution:" uniform_density :: Double -> Double -> Double -> LogDouble
foreign import bpcall "Distribution:" sample_uniform :: Double -> Double -> IO Double
data Uniform = Uniform Double Double
instance Dist Uniform where
type Result Uniform = Double
dist_name _ = "uniform"
instance IOSampleable Uniform where
sampleIO (Uniform l u) = sample_uniform l u
instance HasPdf Uniform where
pdf (Uniform l u) = uniform_density l u
instance Dist1D Uniform where
cdf (Uniform l u) x | x < l = 0
| x < u = (x-l)/(u-l)
| otherwise = 1
lower_bound (Uniform l r) = Just l
upper_bound (Uniform l r) = Just r
instance ContDist1D Uniform where
quantile (Uniform l u) p = l + p*(u-l)
instance MaybeMean Uniform where
maybeMean (Uniform l u) = Just $ (l + u)/2
instance Mean Uniform
instance MaybeVariance Uniform where
maybeVariance (Uniform l u) = Just $ (l-u)^2/12
instance Variance Uniform
instance HasAnnotatedPdf Uniform where
annotated_densities dist@(Uniform l u) x = do
in_edge "l" l
in_edge "u" u
return ([pdf dist x],())
instance Sampleable Uniform where
sample dist@(Uniform l u) = RanDistribution2 dist (uniform_effect l u)
uniform l u = Uniform l u
uniform_bounds l u = between l u
uniform_effect l u x = add_move $ sliceSample x (uniform_bounds l u)
------------------------------------
foreign import bpcall "Distribution:" uniform_int_density :: Int -> Int -> Int -> LogDouble
foreign import bpcall "Distribution:" sample_uniform_int :: Int -> Int -> IO Int
data UniformInt = UniformInt Int Int
instance Dist UniformInt where
type Result UniformInt = Int
dist_name _ = "uniform_int"
instance Dist1D UniformInt where
cdf (UniformInt l u) x | floor x < l = 0
| floor x < u = fromIntegral (floor x-l+1)/ fromIntegral (u-l+1)
| otherwise = 1
lower_bound (UniformInt l u) = Just l
upper_bound (UniformInt l u) = Just u
instance IOSampleable UniformInt where
sampleIO (UniformInt l u) = sample_uniform_int l u
instance HasPdf UniformInt where
pdf (UniformInt l u) = uniform_int_density l u
instance HasAnnotatedPdf UniformInt where
annotated_densities dist = make_densities $ pdf dist
instance Sampleable UniformInt where
sample dist@(UniformInt l u) = RanDistribution2 dist (uniform_int_effect l u)
uniform_int_quantile l u x | x <= l = 0
| x > u = 1
| otherwise = fromIntegral (x-l) / fromIntegral (u-l+1)
uniform_int_bounds l u = integer_between l u
uniform_int_effect l u x = do
-- the slice sampling move refuses to add or remove variables.
addMove (1/3) $ sliceSampleInteger x (uniform_int_bounds l u)
addMove (1/3) $ discreteUniformAvoidMH x l u
addMove (1/3) $ incDecMH x (uniform_int_bounds l u)
uniform_int l u = UniformInt l u
-------------------------------
data UniformD a = UniformD [a]
instance Dist (UniformD a) where
type Result (UniformD a) = a
dist_name _ = "uniformD"
instance IOSampleable (UniformD a) where
sampleIO (UniformD values) = do
index <- sampleIO $ uniform_int 0 (length values-1)
return $ values !! index
instance Eq a => HasPdf (UniformD a) where
pdf (UniformD values) x = sum [ if x == v then 1 else 0 | v <- values] / fromIntegral (length values)
instance Eq a => HasAnnotatedPdf (UniformD a) where
annotated_densities dist = make_densities $ pdf dist
instance Sampleable (UniformD a) where
sample (UniformD values) = do
index <- sample $ uniform_int 0 (length values - 1)
return $ values !! index
uniformD values = UniformD values
|