Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
allendowney
GitHub Repository: allendowney/thinkbayes2
Path: blob/master/scripts/paintball.py
1901 views
1
"""This file contains code used in "Think Bayes",
2
by Allen B. Downey, available from greenteapress.com
3
4
Copyright 2014 Allen B. Downey
5
License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
6
"""
7
8
from __future__ import print_function, division
9
10
import math
11
import sys
12
13
import thinkbayes2
14
import thinkplot
15
16
FORMATS = ['pdf', 'eps', 'png']
17
18
19
def StrafingSpeed(alpha, beta, x):
20
"""Computes strafing speed, given location of shooter and impact.
21
22
alpha: x location of shooter
23
beta: y location of shooter
24
x: location of impact
25
26
Returns: derivative of x with respect to theta
27
"""
28
theta = math.atan2(x - alpha, beta)
29
speed = beta / math.cos(theta)**2
30
return speed
31
32
33
def MakeLocationPmf(alpha, beta, locations):
34
"""Computes the Pmf of the locations, given alpha and beta.
35
36
Given that the shooter is at coordinates (alpha, beta),
37
the probability of hitting any spot is inversely proportionate
38
to the strafe speed.
39
40
alpha: x position
41
beta: y position
42
locations: x locations where the pmf is evaluated
43
44
Returns: Pmf object
45
"""
46
pmf = thinkbayes2.Pmf()
47
for x in locations:
48
prob = 1.0 / StrafingSpeed(alpha, beta, x)
49
pmf.Set(x, prob)
50
pmf.Normalize()
51
return pmf
52
53
54
class Paintball(thinkbayes2.Suite, thinkbayes2.Joint):
55
"""Represents hypotheses about the location of an opponent."""
56
57
def __init__(self, alphas, betas, locations):
58
"""Makes a joint suite of parameters alpha and beta.
59
60
Enumerates all pairs of alpha and beta.
61
Stores locations for use in Likelihood.
62
63
alphas: possible values for alpha
64
betas: possible values for beta
65
locations: possible locations along the wall
66
"""
67
self.locations = locations
68
pairs = [(alpha, beta)
69
for alpha in alphas
70
for beta in betas]
71
thinkbayes2.Suite.__init__(self, pairs)
72
73
def Likelihood(self, data, hypo):
74
"""Computes the likelihood of the data under the hypothesis.
75
76
hypo: pair of alpha, beta
77
data: location of a hit
78
79
Returns: float likelihood
80
"""
81
alpha, beta = hypo
82
x = data
83
pmf = MakeLocationPmf(alpha, beta, self.locations)
84
like = pmf.Prob(x)
85
return like
86
87
88
def MakePmfPlot(alpha = 10):
89
"""Plots Pmf of location for a range of betas."""
90
locations = range(0, 31)
91
92
betas = [10, 20, 40]
93
thinkplot.PrePlot(num=len(betas))
94
95
for beta in betas:
96
pmf = MakeLocationPmf(alpha, beta, locations)
97
pmf.name = 'beta = %d' % beta
98
thinkplot.Pdf(pmf)
99
100
thinkplot.Save('paintball1',
101
xlabel='Distance',
102
ylabel='Prob',
103
formats=FORMATS)
104
105
106
def MakePosteriorPlot(suite):
107
"""Plots the posterior marginal distributions for alpha and beta.
108
109
suite: posterior joint distribution of location
110
"""
111
marginal_alpha = suite.Marginal(0)
112
marginal_alpha.name = 'alpha'
113
marginal_beta = suite.Marginal(1)
114
marginal_beta.name = 'beta'
115
116
print('alpha CI', marginal_alpha.CredibleInterval(50))
117
print('beta CI', marginal_beta.CredibleInterval(50))
118
119
thinkplot.PrePlot(num=2)
120
121
#thinkplot.Pmf(marginal_alpha)
122
#thinkplot.Pmf(marginal_beta)
123
124
thinkplot.Cdf(thinkbayes2.MakeCdfFromPmf(marginal_alpha))
125
thinkplot.Cdf(thinkbayes2.MakeCdfFromPmf(marginal_beta))
126
127
thinkplot.Save('paintball2',
128
xlabel='Distance',
129
ylabel='Prob',
130
loc=4,
131
formats=FORMATS)
132
133
134
def MakeConditionalPlot(suite):
135
"""Plots marginal CDFs for alpha conditioned on beta.
136
137
suite: posterior joint distribution of location
138
"""
139
betas = [10, 20, 40]
140
thinkplot.PrePlot(num=len(betas))
141
142
for beta in betas:
143
cond = suite.Conditional(0, 1, beta)
144
cond.name = 'beta = %d' % beta
145
thinkplot.Pdf(cond)
146
147
thinkplot.Save('paintball3',
148
xlabel='Distance',
149
ylabel='Prob',
150
formats=FORMATS)
151
152
153
def MakeContourPlot(suite):
154
"""Plots the posterior joint distribution as a contour plot.
155
156
suite: posterior joint distribution of location
157
"""
158
thinkplot.Contour(suite.GetDict(), contour=False, pcolor=True)
159
160
thinkplot.Save('paintball4',
161
xlabel='alpha',
162
ylabel='beta',
163
axis=[0, 30, 0, 20],
164
formats=FORMATS)
165
166
167
def MakeCrediblePlot(suite):
168
"""Makes a plot showing several two-dimensional credible intervals.
169
170
suite: Suite
171
"""
172
d = dict((pair, 0) for pair in suite.Values())
173
174
percentages = [75, 50, 25]
175
for p in percentages:
176
interval = suite.MaxLikeInterval(p)
177
for pair in interval:
178
d[pair] += 1
179
180
thinkplot.Contour(d, contour=False, pcolor=True)
181
thinkplot.Text(17, 4, '25', color='white')
182
thinkplot.Text(17, 15, '50', color='white')
183
thinkplot.Text(17, 30, '75')
184
185
thinkplot.Save('paintball5',
186
xlabel='alpha',
187
ylabel='beta',
188
formats=FORMATS,
189
legend=False)
190
191
192
def main(script):
193
194
alphas = range(0, 31)
195
betas = range(1, 51)
196
locations = range(0, 31)
197
198
suite = Paintball(alphas, betas, locations)
199
suite.UpdateSet([15, 16, 18, 21])
200
201
MakeCrediblePlot(suite)
202
203
MakeContourPlot(suite)
204
205
MakePosteriorPlot(suite)
206
207
MakeConditionalPlot(suite)
208
209
MakePmfPlot()
210
211
212
if __name__ == '__main__':
213
main(*sys.argv)
214
215