# Commits

committed b9f403e

test, implement complex copysign, reciprocal

• Participants
• Parent commits 4b6f2ea
• Branches numpypy-complex2

# File pypy/module/micronumpy/test/test_ufuncs.py

`     if not a and not b:`
`         # only check it if we are running on top of CPython >= 2.6`
`         if version_info >= (2, 6) and copysign(1., a) != copysign(1., b):`
`-            return False, msg + 'zero has wrong sign: expected %r, '+ \`
`-                                       'got %r' % (a, b)`
`+            return (False, `
`+                    msg + 'zero has wrong sign: expected %r, got %r' % (a, b))`
` `
`     # if a-b overflows, or b is infinite, return False.  Again, in`
`     # theory there are examples where a is within a few ulps of the`
`         assert (signbit([float('nan'), float('-nan'), -float('nan')]) ==`
`             [False, True, True]).all()    `
` `
`-    def test_reciporocal(self):`
`-        from _numpypy import array, reciprocal`
`+    def test_reciprocal(self):`
`+        from _numpypy import array, reciprocal, complex64, complex128`
` `
`-        reference = [-0.2, float("inf"), float("-inf"), 2.0]`
`-        a = array([-5.0, 0.0, -0.0, 0.5])`
`+        inf = float('inf')`
`+        nan = float('nan')`
`+        reference = [-0.2, inf, -inf, 2.0, nan]`
`+        a = array([-5.0, 0.0, -0.0, 0.5, nan])`
`         b = reciprocal(a)`
`         for i in range(4):`
`             assert b[i] == reference[i]`
` `
`+        #complex    `
`+        fail_at_end = False`
`+        orig = [2.+4.j, -2.+4.j, 2.-4.j, -2.-4.j, `
`+                complex(inf, 3), complex(inf, -3), complex(inf, -inf), `
`+                complex(nan, 3), 0+0j, 0-0j]`
`+        a2 = 2.**2 + 4.**2`
`+        r = 2. / a2`
`+        i = 4. / a2`
`+        cnan = complex(nan, nan)`
`+        expected = [complex(r, -i), complex(-r, -i), complex(r, i), `
`+                    complex(-r, i), `
`+                    -0j, 0j, cnan, `
`+                    cnan, cnan, cnan]`
`+        for c, rel_err in ((complex64, 2e-7), (complex128, 2e-15), ):`
`+            actual = reciprocal(array(orig, dtype=c))`
`+            for b, a, e in zip(orig, actual, expected):`
`+                error_message = (`
`+                    'reciprocal(%r(%r, %r))\n'`
`+                    'Expected: complex(%r, %r)\n'`
`+                    'Received: complex(%r, %r)\n'`
`+                    ) % (c, b.real, b.imag,`
`+                         e.real, e.imag,`
`+                         a.real, a.imag)`
`+                         `
`+                success,msg = self.rAlmostEqual(e.real, a.real,`
`+                               rel_err=rel_err, msg=error_message)`
`+                if not success:`
`+                    if self.collect_all_failures:`
`+                        print msg`
`+                        fail_at_end = True`
`+                    else:`
`+                        raise AssertionError(msg)`
`+                success,msg = self.rAlmostEqual(e.imag, a.imag,`
`+                               rel_err=rel_err, msg=error_message)`
`+                if not success:`
`+                    if self.collect_all_failures:`
`+                        print msg`
`+                        fail_at_end = True`
`+                    else:`
`+                        raise AssertionError(msg)`
`+        if fail_at_end:`
`+            assert False,'at least one test failed, see stdout'`
`+`
`+`
`+`
`     def test_subtract(self):`
`         from _numpypy import array, subtract`
` `
`         assert all([math.copysign(1, f(-abs(float("nan")))) == -1 for f in floor, ceil, trunc])`
` `
`     def test_copysign(self):`
`-        from _numpypy import array, copysign`
`+        from _numpypy import array, copysign, complex64, complex128`
` `
`         reference = [5.0, -0.0, 0.0, -6.0]`
`         a = array([-5.0, 0.0, 0.0, 6.0])`
`         c = copysign(a, b)`
`         for i in range(4):`
`             assert c[i] == abs(a[i])`
`+        for c in complex128, complex64:`
`+            ref  = complex(5., 5.)`
`+            a = c(complex(-5., 5.))`
`+            b = c(complex(0., 0.))`
`+            assert copysign(a,b) == ref`
`+            ref = complex(-5., 5.)`
`+            b = c(complex(-0., 0.))`
`+            assert copysign(a,b) == ref`
`+            a = c(complex(float('inf'), float('inf')))`
`+            ref = complex(-float('inf'), float('inf'))`
`+            assert copysign(a,b) == ref`
` `
`     def test_exp(self):`
`         import math`
`             assert repr(abs(inf_c)) == 'inf'`
`             assert repr(abs(complex(float('nan'), float('nan')))) == 'nan'`
` `
`-        assert False, 'untested: copysign, reciprocal, sign, floor_div, ' + \`
`+        assert False, 'untested: sign, floor_div, ' + \`
`                      'signbit, fabs, fmax, fmin, floor, ceil, trunc, ' + \`
`                      'exp2, expm1, isnan, isinf, isneginf, isposinf, ' + \`
`                      'isfinite, radians, degrees, log2, log1p, ' + \`
`                            float(exp_real), float(exp_imag),`
`                            flags`
`                           )`
`-        tested_funcs=[]`
`         fail_at_end = False`
`         for complex_, abs_err in ((np.complex64, 5e-32), (np.complex128, 5e-323), ):`
`             for id, fn, ar, ai, er, ei, flags in parse_testfile(testcases):`
`                          expected[0], expected[1],`
`                          actual[0], actual[1])`
`                          `
`-                if not function in tested_funcs:        `
`-                    print 'fuction',function`
`-                    tested_funcs.append(function)`
`                 success,msg = self.rAlmostEqual(expected[0], actual[0],`
`                                abs_err=real_abs_err, msg=error_message)`
`                 if not success:`

# File pypy/module/micronumpy/types.py

`     specialize.argtype(1)(func)`
`     @functools.wraps(func)`
`     def dispatcher(self, v):`
`-        try:`
`-            return self.box_complex(`
`-                *func(`
`-                    self,`
`-                    self.for_computation(self.unbox(v))`
`-                )`
`+        return self.box_complex(`
`+            *func(`
`+                self,`
`+                self.for_computation(self.unbox(v))`
`             )`
`-        except:`
`-            import sys`
`-            print >> sys.stderr, "Could not call",func`
`-            raise`
`+        )`
`     return dispatcher`
` `
` def raw_unary_op(func):`
`     def pow(self, v1, v2):`
`         return rcomplex.c_pow(v1, v2)`
` `
`-    @simple_binary_op`
`+    @complex_binary_op`
`     def copysign(self, v1, v2):`
`-        return math.copysign(v1, v2)`
`+        return (rfloat.copysign(v1[0], v2[0]),`
`+               rfloat.copysign(v1[1], v2[1]))`
` `
`     @simple_unary_op`
`     def sign(self, v):`
`     #    except ValueError:`
`     #        return rfloat.NAN`
` `
`-    @simple_unary_op`
`+    @complex_unary_op`
`     def reciprocal(self, v):`
`-        if abs(v) == 0.0:`
`-            return self.copysign(rfloat.INFINITY, v)`
`-        return 1.0 / v`
`+        if math.isinf(v[1]) and math.isinf(v[0]):`
`+            return rfloat.NAN, rfloat.NAN`
`+        if math.isinf(v[0]):`
`+            return (rfloat.copysign(0., v[0]),`
`+                    rfloat.copysign(0., -v[1]))`
`+        a2 = v[0]*v[0] + v[1]*v[1]`
`+        try:`
`+            return rcomplex.c_div((v[0], -v[1]), (a2, 0.))`
`+        except ZeroDivisionError:`
`+            return rfloat.NAN, rfloat.NAN`
` `
`     @simple_unary_op`
`     def floor(self, v):`