changed share fraction displays to include confidence intervals and put them all...
authorForrest Voight <forrest@forre.st>
Mon, 5 Dec 2011 08:16:19 +0000 (03:16 -0500)
committerForrest Voight <forrest@forre.st>
Mon, 5 Dec 2011 08:16:19 +0000 (03:16 -0500)
p2pool/main.py
p2pool/util/math.py

index 21206e1..d7a56ad 100644 (file)
@@ -1,4 +1,5 @@
 #!/usr/bin/python
+# coding=utf-8
 
 from __future__ import division
 
@@ -644,11 +645,14 @@ def main(args, net):
                             pool_str = str;
                         if fracs:
                             med = math.median(fracs)
-                            print 'Median stale proportion:', med
+                            print 'Pool stales: %i%%' % (int(100*med+.5),),
+                            conf = 0.9
                             if shares:
-                                print '    Own:', stale_shares/shares
+                                print 'Own:', '%i±%i%%' % tuple(int(100*x+.5) for x in math.interval_to_center_radius(math.binomial_conf_interval(stale_shares, shares, conf))),
                                 if med < .99:
-                                    print '    Own efficiency: %.02f%%' % (100*(1 - stale_shares/shares)/(1 - med),)
+                                    print 'Own efficiency:', '%i±%i%%' % tuple(int(100*x+.5) for x in math.interval_to_center_radius((1 - y)/(1 - med) for y in math.binomial_conf_interval(stale_shares, shares, conf)[::-1])),
+                                print '(%i%% confidence)' % (int(100*conf+.5),),
+                            print
             
             
             except:
index a1a6794..8d4843b 100644 (file)
@@ -72,6 +72,25 @@ def perfect_round(x):
     else:
         return a2 + 1
 
+def ierf(z, steps=10):
+    guess = 0
+    for i in xrange(steps):
+        d = 2*math.e**(-guess**2)/math.sqrt(math.pi)
+        guess = guess - (math.erf(guess) - z)/d
+    return guess
+
+def binomial_conf_interval(x, n, conf=0.95):
+    # approximate - Wilson score interval
+    z = math.sqrt(2)*ierf(conf)
+    p = x/n
+    topa = p + z**2/2/n
+    topb = z * math.sqrt(p*(1-p)/n + z**2/4/n**2)
+    bottom = 1 + z**2/n
+    return (topa - topb)/bottom, (topa + topb)/bottom
+
+def interval_to_center_radius((low, high)):
+    return (high+low)/2, (high-low)/2
+
 if __name__ == '__main__':
     import random
     a = 1