[pypy-commit] pypy separate-applevel-numpy: implement numpy.bincount with tests

timo_jbo noreply at buildbot.pypy.org
Tue Sep 27 22:04:48 CEST 2011


Author: Timo Paulssen <timonator at perpetuum-immobile.de>
Branch: separate-applevel-numpy
Changeset: r47638:88a4e8b8d916
Date: 2011-09-27 21:43 +0200
http://bitbucket.org/pypy/pypy/changeset/88a4e8b8d916/

Log:	implement numpy.bincount with tests

diff --git a/lib_pypy/numpy/__init__.py b/lib_pypy/numpy/__init__.py
--- a/lib_pypy/numpy/__init__.py
+++ b/lib_pypy/numpy/__init__.py
@@ -46,3 +46,44 @@
     if not hasattr(a, "mean"):
         a = array(a)
     return a.mean()
+
+__SIGNEDLTR = "i"
+__UNSIGNEDLTR = "u"
+
+def bincount(x, weights=None, minlength=None):
+    if minlength is not None:
+        result = [0 for _ in range(minlength)]
+    else:
+        result = [0]
+
+    if len(x) == 0:
+        raise ValueError("the first argument cannot be empty.")
+
+    x = array(x)
+    if x.dtype.kind not in (__SIGNEDLTR, __UNSIGNEDLTR):
+        raise TypeError("array cannot be safely cast to required type")
+
+
+    if len(x.shape) > 1:
+        raise ValueError("object too deep for desired array")
+
+    if weights is not None:
+        weights = array(weights)
+        if weights.shape != x.shape:
+            raise ValueError("The weights and list don't have the same length.")
+
+        num_iter = (num_and_weight for num_and_weight in zip(x, weights))
+
+    else:
+        num_iter = ((num, 1) for num in x)
+
+    for number, weight in num_iter:
+        if number < 0:
+            raise ValueError("The first argument of bincount must be non-negative")
+        try:
+            result[number] += weight
+        except IndexError:
+            result += [0] * (number - len(result)) + [weight]
+
+    return array(result)
+
diff --git a/lib_pypy/pypy_test/test_numpy.py b/lib_pypy/pypy_test/test_numpy.py
--- a/lib_pypy/pypy_test/test_numpy.py
+++ b/lib_pypy/pypy_test/test_numpy.py
@@ -13,3 +13,64 @@
         from numpy import array, average
         assert average(range(10)) == 4.5
         assert average(array(range(10))) == 4.5
+
+    def w_array_compare(self, have, want):
+        assert len(have) == len(want)
+        mismatch = []
+        for num, (x, y) in enumerate(zip(have, want)):
+            if not x == y:
+                mismatch.append(num)
+        if mismatch:
+            print have
+            print want
+            print mismatch
+        assert mismatch == []
+
+    def test_bincount_simple(self):
+        from numpy import array, bincount
+        a = array(range(10))
+        have, want = (bincount(a), array([1] * 10))
+        self.array_compare(have, want)
+        b = array([9, 9, 9, 9, 9])
+        have, want = (bincount(b), array([0] * 9 + [5]))
+        self.array_compare(have, want)
+        c = [9, 9, 9, 9, 9]
+        have, want = (bincount(c), array([0] * 9 + [5]))
+        self.array_compare(have, want)
+
+    def test_bincount_weights(self):
+        from numpy import array, bincount
+        a = array([1, 2, 3, 3, 4, 5])
+        wa = array([-1, 0.1, 0.2, 0.3, 1, 1])
+        have, want = (bincount(a, wa), array([0, -1, 0.1, 0.5, 1, 1]))
+        self.array_compare(have, want)
+        b = [1, 1, 4]
+        wb = [99, -9, 0]
+        have, want = (bincount(b, wb), array([0, 90, 0, 0, 0]))
+        self.array_compare(have, want)
+        c = [1, 1, 1]
+        wc = [9, 8, 7]
+        have, want = (bincount(c, wc, 4), array([0, 24, 0, 0]))
+        self.array_compare(have, want)
+
+    def test_array_compare(self):
+        # just some sanity-checks for the comparison function
+        from numpy import array
+        a = array([1, 2, 4])
+        b = array([1, 1, 1])
+        raises(AssertionError, "self.array_compare(a, b)")
+        x = array([1, 1, 4])
+        y = array([1, 1])
+        raises(AssertionError, "self.array_compare(x, y)")
+
+    def test_bincount_error_handling(self):
+        from numpy import array, bincount
+        a = array([1.0, 2.0, 3.0], float)
+        raises(TypeError, "bincount(a)")
+        b = array([-1, -2, -3])
+        raises(ValueError, "bincount(b)")
+        c = array([0, 1, 2])
+        w = array([1, 2])
+        raises(ValueError, "bincount(c, w)")
+        raises(ValueError, "bincount([])")
+


More information about the pypy-commit mailing list