-
Notifications
You must be signed in to change notification settings - Fork 1
/
Likelihood.py
236 lines (199 loc) · 6.54 KB
/
Likelihood.py
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
import numpy as np
import scipy as sp
from scipy import special
from scipy import stats
def gammaPriorPoissonLikelihood(k, alpha, beta):
"""Poisson distribution marginalized over the rate parameter, priored with
a gamma distribution that has shape parameter alpha and inverse rate
parameter beta.
Parameters
----------
k : int
The number of observed events
alpha : float
Gamma distribution shape parameter
beta : float
Gamma distribution inverse rate parameter
Returns
-------
float
The log likelihood
"""
values = [
alpha*np.log(beta),
sp.special.loggamma(k+alpha).real,
-sp.special.loggamma(k+1.0).real,
-(k+alpha)*np.log1p(beta),
-sp.special.loggamma(alpha).real,
]
return np.sum(values)
def poissonLikelihood(k, weight_sum, weight_sq_sum):
"""Computes Log of the Poisson Likelihood.
Parameters
----------
k : int
the number of observed events
weight_sum : float
the sum of the weighted MC event counts
weight_sq_sum : float
the sum of the square of the weighted MC event counts
Returns
-------
float
The log likelihood
"""
return sp.stats.poisson.logpmf(k, weight_sum)
def LMean(k, weight_sum, weight_sq_sum):
"""Computes Log of the L_Mean Likelihood.
This is the poisson likelihood with gamma distribution prior where the
mean and variance are fixed to that of the weight distribution.
Parameters
----------
k : int
the number of observed events
weight_sum : float
the sum of the weighted MC event counts
weight_sq_sum : float
the sum of the square of the weighted MC event counts
Returns
-------
float
The log likelihood
"""
# Return -inf for ill formed an likelihood or 0 without observation
if weight_sum <= 0 or weight_sq_sum < 0:
if k == 0:
return 0
else:
return -np.inf
# Return the poisson likelihood in the appropriate limiting case
if weight_sq_sum == 0:
return poissonLikelihood(k, weight_sum, weight_sq_sum)
alpha = np.power(weight_sum, 2.0) / weight_sq_sum
beta = weight_sum / weight_sq_sum
L = gammaPriorPoissonLikelihood(k, alpha, beta)
return L
def LMode(k, weight_sum, weight_sq_sum):
"""Computes Log of the L_Mode Likelihood.
This is the poisson likelihood with gamma distribution prior where the
mode and variance are fixed to that of the weight distribution.
Parameters
----------
k : int
the number of observed events
weight_sum : float
the sum of the weighted MC event counts
weight_sq_sum : float
the sum of the square of the weighted MC event counts
Returns
-------
float
The log likelihood
"""
# Return -inf for ill formed an likelihood or 0 without observation
if weight_sum <= 0 or weight_sq_sum < 0:
if k == 0:
return 0
else:
return -np.inf
# Return the poisson likelihood in the appropriate limiting case
if weight_sq_sum == 0:
return poissonLikelihood(k, weight_sum, weight_sq_sum)
mu = weight_sum
mu2 = np.power(mu, 2.0)
sigma2 = weight_sq_sum
beta = (mu + np.sqrt(mu2 + sigma2*4.0))/(sigma2*2.0)
alpha = (mu*np.sqrt(mu2 + sigma2*4.0)/sigma2 + mu2/sigma2 + 2.0)/2.0
L = gammaPriorPoissonLikelihood(k, alpha, beta)
return L
def LEff(k, weight_sum, weight_sq_sum):
"""Computes Log of the L_Eff Likelihood.
This is the poisson likelihood, using a poisson distribution with
rescaled rate parameter to describe the Monte Carlo expectation, and
assuming a uniform prior on the rate parameter of the Monte Carlo.
This is the main result of the paper arXiv:1901.04645
Parameters
----------
k : int
the number of observed events
weight_sum : float
the sum of the weighted MC event counts
weight_sq_sum : float
the sum of the square of the weighted MC event counts
Returns
-------
float
The log likelihood
"""
# Return -inf for ill formed an likelihood or 0 without observation
if weight_sum <= 0 or weight_sq_sum < 0:
if k == 0:
return 0
else:
return -np.inf
# Return the poisson likelihood in the appropriate limiting case
if weight_sq_sum == 0:
return poissonLikelihood(k, weight_sum, weight_sq_sum)
alpha = np.power(weight_sum, 2.0) / weight_sq_sum + 1.0
beta = weight_sum / weight_sq_sum
L = gammaPriorPoissonLikelihood(k, alpha, beta)
return L
def computeLMean(k, weights):
"""Computes Log of the L_Mean Likelihood from a list of weights.
This is the poisson likelihood with gamma distribution prior where the
mean and variance are fixed to that of the weight distribution.
Parameters
----------
k : int
the number of observed events
weights : [float]
the list of the weighted MC events
Returns
-------
float
The log likelihood
"""
w = np.asarray(weights)
weight_sum = np.sum(w)
weight_sq_sum = np.sum(w*w)
return LMean(k, weight_sum, weight_sq_sum)
def computeLMode(k, weights):
"""Computes Log of the L_Mode Likelihood from a list of weights.
This is the poisson likelihood with gamma distribution prior where the
mode and variance are fixed to that of the weight distribution.
Parameters
----------
k : int
the number of observed events
weights : [float]
the list of the weighted MC events
Returns
-------
float
The log likelihood
"""
w = np.asarray(weights)
weight_sum = np.sum(w)
weight_sq_sum = np.sum(w*w)
return LMode(k, weight_sum, weight_sq_sum)
def computeLEff(k, weights):
"""Computes Log of the L_Eff Likelihood from a list of weights.
This is the poisson likelihood, using a poisson distribution with
rescaled rate parameter to describe the Monte Carlo expectation, and
assuming a uniform prior on the rate parameter of the Monte Carlo.
This is the main result of the paper arXiv:1901.04645
Parameters
----------
k : int
the number of observed events
weights : [float]
the list of the weighted MC events
Returns
-------
float
The log likelihood
"""
w = np.asarray(weights)
weight_sum = np.sum(w)
weight_sq_sum = np.sum(w*w)
return LEff(k, weight_sum, weight_sq_sum)