Bob Ippolito avatar Bob Ippolito committed 50e7857

Bring in an accurate sum() implementation for array operators
... We should devise some tests to see if we're more accurate than the
native Foundation implementation :)

Comments (0)

Files changed (1)

Lib/PyObjCTools/KeyValueCoding.py

 def keyCaps(s):
     return s[:1].capitalize() + s[1:]
 
+# From http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/393090
+# Title: Binary floating point summation accurate to full precision
+# Version no: 2.2
+
+def msum(iterable):
+    "Full precision summation using multiple floats for intermediate values"
+    # sorted, non-overlapping partial sums
+    partials = []
+    for x in iterable:
+        i = 0
+        for y in partials:
+            if abs(x) < abs(y):
+                x, y = y, x
+            hi = x + y
+            lo = y - (hi - x)
+            if lo:
+                partials[i] = lo
+                i += 1
+            x = hi
+        partials[i:] = [x]
+    return sum(partials, 0.0)
+
 class ArrayOperators(object):
     def avg(self, obj, segments):
         path = u'.'.join(segments)
         count = len(lst)
         if count == 0:
             return 0.0
-        # XXX: Use a more accurate algorithm
-        return sum(imap(float, lst), 0.0) / count
+        return msum(imap(float, lst)) / count
     
     def count(self, obj, segments):
         return len(obj)
     def sum(self, obj, segments):
         path = u'.'.join(segments)
         lst = getKeyPath(obj, path)
-        # XXX: Use a more accurate algorithm
-        return sum(imap(float, lst), 0.0)
+        return msum(imap(float, lst))
 
     def unionOfArrays(self, obj, segments):
         path = u'.'.join(segments)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.