rb_probdsl 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/examples/alarm.rb +12 -12
- data/examples/diagnosis.rb +1 -1
- data/examples/montyhall.rb +2 -2
- data/examples/paradox.rb +2 -2
- data/examples/test.rb +9 -9
- data/lib/probdsl.rb +46 -30
- metadata +27 -14
data/examples/alarm.rb
CHANGED
@@ -75,16 +75,16 @@ def p_mary(a)
|
|
75
75
|
flip( a == :A ? 0.7 : 0.01, :M, :notM)
|
76
76
|
end
|
77
77
|
|
78
|
-
|
79
|
-
|
78
|
+
puts "\njoint probability:"
|
79
|
+
puts(prob do
|
80
80
|
b = p_burglary
|
81
81
|
e = p_earthquake
|
82
82
|
a = p_alarm(b,e)
|
83
83
|
[b,e,a,p_john(a), p_mary(a)]
|
84
84
|
end)
|
85
85
|
|
86
|
-
|
87
|
-
|
86
|
+
puts "\nP(B|John=true, Mary=true):"
|
87
|
+
puts(norm_prob do
|
88
88
|
b = p_burglary
|
89
89
|
e = p_earthquake
|
90
90
|
a = p_alarm(b,e)
|
@@ -95,8 +95,8 @@ p(normalizedProb do
|
|
95
95
|
end
|
96
96
|
end)
|
97
97
|
|
98
|
-
|
99
|
-
|
98
|
+
puts "\nP(A|John=true, Mary=true)"
|
99
|
+
puts(norm_prob do
|
100
100
|
b = p_burglary
|
101
101
|
e = p_earthquake
|
102
102
|
a = p_alarm(b, e)
|
@@ -109,8 +109,8 @@ end)
|
|
109
109
|
|
110
110
|
# john and mary tell us for sure, the alarm went of and we know
|
111
111
|
# that is true...
|
112
|
-
|
113
|
-
|
112
|
+
puts "\nP(B|John=true, Mary=true, Alarm=true)"
|
113
|
+
puts(norm_prob do
|
114
114
|
b = p_burglary
|
115
115
|
e = p_earthquake
|
116
116
|
a = p_alarm(b,e)
|
@@ -122,8 +122,8 @@ p(normalizedProb do
|
|
122
122
|
end)
|
123
123
|
|
124
124
|
# what is the probability john will call, if mary called?
|
125
|
-
|
126
|
-
|
125
|
+
puts "\nP(John|Mary=true)"
|
126
|
+
puts(norm_prob do
|
127
127
|
b = p_burglary
|
128
128
|
e = p_earthquake
|
129
129
|
a = p_alarm(b,e)
|
@@ -135,8 +135,8 @@ p(normalizedProb do
|
|
135
135
|
end)
|
136
136
|
|
137
137
|
# and probability mary will call, if john did
|
138
|
-
|
139
|
-
|
138
|
+
puts "\nP(Mary|John=true)"
|
139
|
+
puts(norm_prob do
|
140
140
|
b = p_burglary
|
141
141
|
e = p_earthquake
|
142
142
|
a = p_alarm(b,e)
|
data/examples/diagnosis.rb
CHANGED
data/examples/montyhall.rb
CHANGED
@@ -98,8 +98,8 @@ end
|
|
98
98
|
|
99
99
|
# print some results
|
100
100
|
p 'strategy stay:'
|
101
|
-
|
101
|
+
puts(prob { stay(firstRound).testWinner })
|
102
102
|
|
103
103
|
p 'strategy switch:'
|
104
|
-
|
104
|
+
puts(prob { switch(firstRound).testWinner })
|
105
105
|
|
data/examples/paradox.rb
CHANGED
@@ -18,7 +18,7 @@ the probability that the total on the uppermost faces of the two dice is "7"?
|
|
18
18
|
Answear (2/11):
|
19
19
|
HERE
|
20
20
|
|
21
|
-
|
21
|
+
puts norm_prob {
|
22
22
|
d1 = die; d2 = die
|
23
23
|
if d1 == 4 || d2 == 4
|
24
24
|
d1 + d2 == 7
|
@@ -31,7 +31,7 @@ puts <<HERE
|
|
31
31
|
|
32
32
|
The same experiment using a simulation (t = 10s):
|
33
33
|
HERE
|
34
|
-
|
34
|
+
puts collecting(loop_t 10) {
|
35
35
|
d1 = die; d2 = die
|
36
36
|
if d1 == 4 || d2 == 4
|
37
37
|
d1 + d2 == 7
|
data/examples/test.rb
CHANGED
@@ -4,9 +4,9 @@ require 'rubygems'
|
|
4
4
|
require 'probdsl'
|
5
5
|
include ProbDSL
|
6
6
|
|
7
|
-
|
7
|
+
puts "test1"
|
8
8
|
|
9
|
-
|
9
|
+
puts(prob {
|
10
10
|
d = uniform [1,2,3,4,5,6]
|
11
11
|
d
|
12
12
|
})
|
@@ -23,7 +23,7 @@ def dice
|
|
23
23
|
[d1, d2]
|
24
24
|
end
|
25
25
|
|
26
|
-
|
26
|
+
puts(prob {
|
27
27
|
d1 = die
|
28
28
|
d2 = die
|
29
29
|
d1 + d2
|
@@ -31,17 +31,17 @@ p(prob {
|
|
31
31
|
|
32
32
|
p 'test3'
|
33
33
|
|
34
|
-
|
34
|
+
puts(prob{ die + die })
|
35
35
|
|
36
36
|
p 'test4'
|
37
37
|
|
38
|
-
|
38
|
+
puts(pick {
|
39
39
|
dice
|
40
40
|
})
|
41
41
|
|
42
42
|
p 'test5'
|
43
43
|
|
44
|
-
|
44
|
+
puts(prob {
|
45
45
|
d1, d2 = dice
|
46
46
|
d1 + d2
|
47
47
|
})
|
@@ -49,20 +49,20 @@ p(prob {
|
|
49
49
|
p 'test6'
|
50
50
|
tmp = prob{ dice }
|
51
51
|
|
52
|
-
|
52
|
+
puts(prob {
|
53
53
|
d1, d2 = dist(tmp) # this time use already evaluated distribution
|
54
54
|
d1 + d2
|
55
55
|
})
|
56
56
|
|
57
57
|
p 'test7'
|
58
58
|
|
59
|
-
|
59
|
+
puts(collecting(loop_k 1000) {
|
60
60
|
die + die
|
61
61
|
})
|
62
62
|
|
63
63
|
p 'test8'
|
64
64
|
|
65
|
-
|
65
|
+
puts(collecting(loop_t 30) {
|
66
66
|
die + die
|
67
67
|
})
|
68
68
|
|
data/lib/probdsl.rb
CHANGED
@@ -8,13 +8,25 @@ module ProbDSL
|
|
8
8
|
include DelimCC
|
9
9
|
include Probably
|
10
10
|
|
11
|
+
class PNone
|
12
|
+
def reify
|
13
|
+
nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def pick
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
PNil = PNone.new
|
22
|
+
|
11
23
|
class PValue
|
12
24
|
def initialize(v)
|
13
25
|
@value = v
|
14
26
|
end
|
15
27
|
|
16
28
|
def reify
|
17
|
-
Probably.
|
29
|
+
Probably.mk_const @value
|
18
30
|
end
|
19
31
|
|
20
32
|
def pick
|
@@ -22,6 +34,9 @@ module ProbDSL
|
|
22
34
|
end
|
23
35
|
end
|
24
36
|
|
37
|
+
# Tree Node in Decision tree.
|
38
|
+
# All sub nodes are unevaluated, so tree expansion is lazy
|
39
|
+
# and therefore different evaluation strategies may be implemented.
|
25
40
|
class PChoice
|
26
41
|
def initialize(&blk)
|
27
42
|
@fn = blk
|
@@ -38,19 +53,22 @@ module ProbDSL
|
|
38
53
|
end
|
39
54
|
|
40
55
|
def pick
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
tmp.pick
|
56
|
+
dist = @fn.call
|
57
|
+
picked,probability = dist.pick
|
58
|
+
cont = picked[0]
|
59
|
+
value = picked[1]
|
60
|
+
cont.call(value).pick
|
47
61
|
end
|
48
62
|
end
|
49
63
|
|
50
64
|
def run_prob(&blk)
|
51
65
|
reset {
|
52
|
-
|
53
|
-
|
66
|
+
value = blk.call
|
67
|
+
if value == nil
|
68
|
+
PNil
|
69
|
+
else
|
70
|
+
PValue.new value
|
71
|
+
end
|
54
72
|
}
|
55
73
|
end
|
56
74
|
|
@@ -58,7 +76,7 @@ module ProbDSL
|
|
58
76
|
run_prob(&blk).reify
|
59
77
|
end
|
60
78
|
|
61
|
-
def
|
79
|
+
def norm_prob(&blk)
|
62
80
|
prob(&blk).normalize
|
63
81
|
end
|
64
82
|
|
@@ -67,44 +85,42 @@ module ProbDSL
|
|
67
85
|
end
|
68
86
|
|
69
87
|
def collect(pred, tree)
|
70
|
-
|
88
|
+
tmp = Hash.new(0)
|
71
89
|
while (pred.call)
|
72
|
-
|
73
|
-
m[x] += 1.0
|
90
|
+
tmp[tree.pick] += 1.0
|
74
91
|
end
|
75
|
-
Distribution.new :MAP,
|
92
|
+
Distribution.new :MAP, tmp
|
76
93
|
end
|
77
94
|
|
78
95
|
def collecting(pred, &blk)
|
79
96
|
collect(pred, run_prob(&blk))
|
80
97
|
end
|
81
98
|
|
82
|
-
def loop_k(
|
83
|
-
tmp =
|
99
|
+
def loop_k(ktimes)
|
100
|
+
tmp = ktimes
|
84
101
|
proc {
|
85
|
-
|
102
|
+
ret = tmp > 0
|
86
103
|
tmp-=1
|
87
|
-
|
104
|
+
ret
|
88
105
|
}
|
89
106
|
end
|
90
107
|
|
91
|
-
def loop_t(
|
108
|
+
def loop_t(seconds)
|
92
109
|
start = Time.now
|
93
110
|
proc {
|
94
|
-
(Time.now - start) <
|
111
|
+
(Time.now - start) < seconds
|
95
112
|
}
|
96
113
|
end
|
97
114
|
|
98
115
|
def dist(data)
|
99
|
-
shift { |
|
116
|
+
shift { |cont|
|
100
117
|
PChoice.new do
|
101
|
-
|
102
|
-
data.each do |
|
103
|
-
|
104
|
-
m[tmp] += p
|
118
|
+
map = Hash.new(0)
|
119
|
+
data.each do |prob, dist|
|
120
|
+
map[[cont, dist]] += prob
|
105
121
|
end
|
106
122
|
|
107
|
-
Distribution.new :MAP,
|
123
|
+
Distribution.new :MAP, map
|
108
124
|
end
|
109
125
|
}
|
110
126
|
end
|
@@ -113,14 +129,14 @@ module ProbDSL
|
|
113
129
|
dist(data.map {|x| [1, x]})
|
114
130
|
end
|
115
131
|
|
116
|
-
def flip(
|
132
|
+
def flip(prob, *data)
|
117
133
|
case data.length
|
118
134
|
when 0
|
119
|
-
dist [[
|
135
|
+
dist [[prob, true], [1 - prob, false]]
|
120
136
|
when 1
|
121
|
-
dist [[
|
137
|
+
dist [[prob, data[0]], [1 - prob, nil]]
|
122
138
|
when 2
|
123
|
-
dist [[
|
139
|
+
dist [[prob, data[0]], [1 - prob, data[1]]]
|
124
140
|
else
|
125
141
|
raise 'illegal number of arguments'
|
126
142
|
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rb_probdsl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Steffen Siering
|
@@ -9,29 +14,35 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-03-
|
17
|
+
date: 2010-03-24 00:00:00 +01:00
|
13
18
|
default_executable:
|
14
19
|
dependencies:
|
15
20
|
- !ruby/object:Gem::Dependency
|
16
21
|
name: rb_prob
|
17
|
-
|
18
|
-
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
24
|
requirements:
|
21
25
|
- - ">="
|
22
26
|
- !ruby/object:Gem::Version
|
23
|
-
|
24
|
-
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 0
|
30
|
+
- 2
|
31
|
+
version: 0.0.2
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
25
34
|
- !ruby/object:Gem::Dependency
|
26
35
|
name: rb_delimcc
|
27
|
-
|
28
|
-
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
30
38
|
requirements:
|
31
39
|
- - ">="
|
32
40
|
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
33
43
|
version: "0"
|
34
|
-
|
44
|
+
type: :runtime
|
45
|
+
version_requirements: *id002
|
35
46
|
description:
|
36
47
|
email: steffen <dot> siering -> gmail <dot> com
|
37
48
|
executables: []
|
@@ -61,18 +72,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
61
72
|
requirements:
|
62
73
|
- - ">="
|
63
74
|
- !ruby/object:Gem::Version
|
75
|
+
segments:
|
76
|
+
- 0
|
64
77
|
version: "0"
|
65
|
-
version:
|
66
78
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
79
|
requirements:
|
68
80
|
- - ">="
|
69
81
|
- !ruby/object:Gem::Version
|
82
|
+
segments:
|
83
|
+
- 0
|
70
84
|
version: "0"
|
71
|
-
version:
|
72
85
|
requirements: []
|
73
86
|
|
74
87
|
rubyforge_project:
|
75
|
-
rubygems_version: 1.3.
|
88
|
+
rubygems_version: 1.3.6
|
76
89
|
signing_key:
|
77
90
|
specification_version: 3
|
78
91
|
summary: do probabilistic programming in ruby
|