ra4_stats  0341147a0dc35f80f4e12c6003afb76a38e2ed6e
wilks_coverage.py
Go to the documentation of this file.
1 #! /usr/bin/env python
2 
3 from __future__ import print_function
4 
5 import argparse
6 import math
7 import scipy.stats
8 
9 import ROOT
10 
11 def lower_bound(N):
12  if N <= 0.:
13  return 0.
14 
15  target = N*math.log(N)-N-0.5
16  bot = 0.
17  top = N
18  mid = bot+0.5*(top-bot)
19  while top>mid and mid>bot:
20  if N*math.log(mid)-mid >= target:
21  top = mid
22  else:
23  bot = mid
24  mid = bot+0.5*(top-bot)
25  return mid
26 
27 def upper_bound(N):
28  if N <= 0.:
29  return 1.
30  target = N*math.log(N)-N-0.5
31  bot = N
32  top = max(20., N+5.*math.sqrt(N))
33  mid = bot+0.5*(top-bot)
34  while top>mid and mid>bot:
35  if N*math.log(mid)-mid > target:
36  bot = mid
37  else:
38  top = mid
39  mid = bot+0.5*(top-bot)
40  return mid
41 
42 def get_bounds(upper):
43  bounds = dict()
44  for N in range(upper):
45  bounds[N] = (lower_bound(N), upper_bound(N))
46  return bounds
47 
48 def get_coverage(mu, bounds):
49  p = 0.
50  for N in bounds:
51  bound = bounds[N]
52  if mu >= bound[0] and mu < bound[1]:
53  p += scipy.stats.poisson.pmf(N, mu)
54  return p
55 
56 def test_wilks_coverage(num_pts, lower_lim, upper_lim):
57  bounds = get_bounds(int(round(max(20, upper_lim+5.*math.sqrt(upper_lim)))))
58 
59  h = ROOT.TH1D("", "Wilk's Coverage;Poisson mean #mu;Coverage", num_pts, lower_lim, upper_lim)
60  g = ROOT.TH1D("", "Wilk's Coverage;Poisson mean #mu;Coverage", num_pts, lower_lim, upper_lim)
61 
62  h.SetStats(False)
63  h.SetTitleOffset(1.25, "Y")
64  h.SetLineColor(ROOT.kRed)
65  g.SetLineColor(ROOT.kBlack)
66  g.SetLineStyle(2)
67 
68  ref_val = math.erf(1/math.sqrt(2.))
69  for i in range(1, num_pts+1):
70  mu = h.GetBinCenter(i)
71  h.SetBinContent(i, get_coverage(mu, bounds))
72  g.SetBinContent(i, ref_val)
73 
74  c = ROOT.TCanvas()
75  h.Draw("L")
76  g.Draw("L same")
77  c.Print("wilks_coverage.pdf")
78 
79 if __name__ == "__main__":
80  parser = argparse.ArgumentParser(description="Test coverage of Poisson intervals from Wilk's theorem",
81  formatter_class=argparse.ArgumentDefaultsHelpFormatter)
82  parser.add_argument("--num_pts", type=int, default=1000, help="Number of points at which to evaluate function")
83  parser.add_argument("--low", type=float, default=0., help="Lower limit of tested range")
84  parser.add_argument("--high", type=float, default=20., help="Upper limit of tested range")
85 
86  args = parser.parse_args()
87 
88  test_wilks_coverage(args.num_pts, args.low, args.high)
def get_coverage(mu, bounds)
def test_wilks_coverage(num_pts, lower_lim, upper_lim)
def get_bounds(upper)