File: Cauchy.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 (78 lines) | stat: -rw-r--r-- 2,345 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
module Probability.Distribution.Cauchy where

import Probability.Random
import MCMC

---- cauchy

foreign import bpcall "Distribution:" cauchy_density :: Double -> Double -> Double -> LogDouble
foreign import bpcall "Distribution:" cauchy_quantile :: Double -> Double -> Double -> Double
foreign import bpcall "Distribution:" sample_cauchy :: Double -> Double -> IO Double

cauchy_bounds = realLine
cauchy_effect x = add_move $ sliceSample x cauchy_bounds

data Cauchy = Cauchy Double Double

instance Dist Cauchy where
    type Result Cauchy = Double
    dist_name _ = "Cauchy"

instance IOSampleable Cauchy where
    sampleIO (Cauchy m s) = sample_cauchy m s

instance HasPdf Cauchy where
    pdf (Cauchy m s) x = cauchy_density m s x

instance Dist1D Cauchy where
    cdf (Cauchy m s) x = undefined

instance ContDist1D Cauchy where
    quantile (Cauchy m s) p = cauchy_quantile m s p

instance HasAnnotatedPdf Cauchy where
    annotated_densities dist@(Cauchy m s) x = do
       in_edge "m" m
       in_edge "s" s
       return ([pdf dist x],())

instance Sampleable Cauchy where
    sample dist@(Cauchy mu sigma) = RanDistribution2 dist cauchy_effect

cauchy m s = Cauchy m s

---- half_cauchy

-- Let's assume that the distribution is (i) continuous and (ii) symmetric around 0.

data Half d = (Result d ~ Double) => Half d

instance Dist d => Dist (Half d) where
    type Result (Half d) = Double
    dist_name dist = "Half" ++ dist_name dist

instance IOSampleable d => IOSampleable (Half d) where
    sampleIO (Half dist) = abs <$> sampleIO dist

-- Ignoring 0 assumes the distribution is continuous.
instance HasPdf d => HasPdf (Half d) where
    pdf (Half dist) x | x < 0     = 0
                      | x == 0    = pdf dist x
                      | otherwise = pdf dist x + pdf dist (-x)

instance Dist1D d => Dist1D (Half d) where
    cdf (Half dist) x  | x > 0     = cdf dist x - cdf dist (-x)
                       | otherwise = 0

-- This assumes that dist is symmetric around 0.
instance ContDist1D d => ContDist1D (Half d) where
    quantile (Half dist) p = quantile dist ((p+1)/2)

instance HasPdf d => HasAnnotatedPdf (Half d) where
    annotated_densities dist = make_densities $ pdf dist

instance Sampleable d => Sampleable (Half d) where
    sample (Half dist) = abs <$> sample dist

half_cauchy s = Half $ cauchy 0 s