File: Poisson.hs

package info (click to toggle)
bali-phy 4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 15,392 kB
  • sloc: cpp: 120,442; xml: 13,966; haskell: 9,975; python: 2,936; yacc: 1,328; perl: 1,169; lex: 912; sh: 343; makefile: 26
file content (125 lines) | stat: -rw-r--r-- 4,053 bytes parent folder | download | duplicates (2)
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
124
125
module Probability.Distribution.Poisson where

import Probability.Random
import MCMC
import Probability.Distribution.List
import Probability.Distribution.Uniform

foreign import bpcall "Distribution:" poisson_density :: Double -> Int -> LogDouble
foreign import bpcall "Distribution:" sample_poisson :: Double -> IO Int

data Poisson = Poisson Double

instance Dist Poisson where
    type Result Poisson = Int
    dist_name _ = "poisson"

instance IOSampleable Poisson where
    sampleIO (Poisson mu) = sample_poisson mu

instance HasPdf Poisson where
    pdf (Poisson mu) n = poisson_density mu n

instance Dist1D Poisson where
    cdf (Poisson mu) = undefined
    lower_bound _ = Just 0

instance MaybeMean Poisson where
    maybeMean (Poisson mu) = Just mu

instance Mean Poisson

instance MaybeVariance Poisson where
    maybeVariance (Poisson mu)= Just mu

instance Variance Poisson

instance HasAnnotatedPdf Poisson where
    annotated_densities dist@(Poisson mu) n = do
        in_edge "mu" mu
        return ([pdf dist n], ())

instance Sampleable Poisson where
    sample dist = RanDistribution2 dist poisson_effect
    
poisson_bounds = integer_above 0

poisson_effect x = do
   add_move $ sliceSampleInteger x poisson_bounds
   add_move $ incDecMH x poisson_bounds

poisson mu = Poisson mu

------------------------------------------------------------
data PoissonProcess = PoissonProcess Double Double Double

instance Dist PoissonProcess where
    type Result PoissonProcess = [Double]
    dist_name _ = "poisson_process"

instance IOSampleable PoissonProcess where
    sampleIO (PoissonProcess rate t1 t2) = do
       n <- sampleIO $ poisson (rate * (t2-t1))
       xs <- sampleIO $ iid n (uniform t1 t2)
       return $ sort xs

instance HasPdf PoissonProcess where
    pdf (PoissonProcess rate t1 t2) = poisson_process_density rate t1 t2

instance Sampleable PoissonProcess where
    sample (PoissonProcess rate t1 t2) = do
       n <- sample $ poisson (rate * (t2-t1))
       xs <- sample $ iid n (uniform t1 t2)
       return $ sort xs

instance HasAnnotatedPdf PoissonProcess where
    annotated_densities (PoissonProcess rate t1 t2) = make_densities $ poisson_process_density rate t1 t2

--- Poisson process, constant rate --
poisson_process_density' rate t1 t2 n = expTo $ (-rate*(t2-t1)) + (fromIntegral n * log rate)
poisson_process_density  rate t1 t2 points = poisson_process_density' rate t1 t2 n where n = length points
sample_poisson_process rate t1 t2 = do
  n <- sample $ poisson (rate * (t2-t1))
  xs <- sample $ iid n (uniform t1 t2)
  return $ sort xs

--- Poisson process, piecewise constant

poisson_process rate t1 t2 = PoissonProcess rate t1 t2

------------------------------------------------------------
data PoissonProcesses = PoissonProcesses [(Double,Double,Double)]

instance Dist PoissonProcesses where
    type Result PoissonProcesses = [Double]
    dist_name _ = "poisson_processes"

instance HasPdf PoissonProcesses where
    pdf dist = density dist

instance HasAnnotatedPdf PoissonProcesses where
    annotated_densities (PoissonProcesses intervals) = make_densities' $ poisson_processes_densities intervals

instance Sampleable PoissonProcesses where
    sample (PoissonProcesses intervals) = sample_poisson_processes intervals

dropCount p xs = go p 0 xs where
    go p n [] = (n,[])
    go p n xs@(x:xs') | p x        = go p (n+1) xs'
                      | otherwise  = (n,xs)

poisson_processes_densities [] [] = []
poisson_processes_densities [] _  = [0]
poisson_processes_densities ((rate,t1,t2):intervals) points = poisson_process_density' rate t1 t2 n:poisson_processes_densities intervals remaining_points
    where (n,remaining_points) = dropCount (<= t2) points

sample_poisson_processes [] = return []
sample_poisson_processes ((rate,t1,t2):intervals) = do
  points1 <- sample_poisson_process rate t1 t2
  points2 <- sample_poisson_processes intervals
  -- FIXME - this doesn't seem very efficient!
  return $ points1 ++ points2


poisson_processes intervals = PoissonProcesses intervals