[pypy-commit] pypy numpypy-complex2: add last tests

mattip noreply at buildbot.pypy.org
Mon Sep 24 22:15:18 CEST 2012


Author: mattip <matti.picus at gmail.com>
Branch: numpypy-complex2
Changeset: r57518:2267f8834f39
Date: 2012-09-24 22:10 +0200
http://bitbucket.org/pypy/pypy/changeset/2267f8834f39/

Log:	add last tests

diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -584,8 +584,10 @@
             ("log2", "log2", 1, {"promote_to_float": True}),
             ("log10", "log10", 1, {"promote_to_float": True}),
             ("log1p", "log1p", 1, {"promote_to_float": True}),
-            ("logaddexp", "logaddexp", 2, {"promote_to_float": True}),
-            ("logaddexp2", "logaddexp2", 2, {"promote_to_float": True}),
+            ("logaddexp", "logaddexp", 2, {"promote_to_float": True,
+                                       "allow_complex": False}),
+            ("logaddexp2", "logaddexp2", 2, {"promote_to_float": True,
+                                       "allow_complex": False}),
         ]:
             self.add_ufunc(space, *ufunc_def)
 
diff --git a/pypy/module/micronumpy/test/complex_testcases.txt b/pypy/module/micronumpy/test/complex_testcases.txt
--- a/pypy/module/micronumpy/test/complex_testcases.txt
+++ b/pypy/module/micronumpy/test/complex_testcases.txt
@@ -1639,7 +1639,7 @@
 exp1020 exp inf 5.6 -> inf -inf
 exp1021 exp inf 7.0 -> inf inf
 exp1022 exp -inf inf -> 0 0         ignore-real-sign ignore-imag-sign
-exp1023 exp inf inf -> nan nan          invalid ignore-real-sign
+exp1023 exp inf inf -> inf nan          invalid ignore-real-sign
 exp1024 exp -inf nan -> nan nan         ignore-real-sign ignore-imag-sign
 exp1025 exp inf nan -> nan nan          ignore-real-sign
 exp1026 exp nan 0.0 -> nan 0.0
diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py
--- a/pypy/module/micronumpy/test/test_complex.py
+++ b/pypy/module/micronumpy/test/test_complex.py
@@ -198,10 +198,6 @@
             for i in range(len(a)):
                 try:
                     res = self.c_pow((2,0), (a[i].real, a[i].imag))
-                    if a[i].imag == 0. and math.copysign(1., a[i].imag)<0:
-                        res = (res[0], -0.)
-                    elif a[i].imag == 0.:
-                        res = (res[0], 0.)
                 except OverflowError:
                     res = (inf, nan)
                 except ValueError:
@@ -266,13 +262,16 @@
 
     def test_not_complex(self):
         from _numpypy import (radians, deg2rad, degrees, rad2deg,
-                      isneginf, isposinf)
+                  isneginf, isposinf, logaddexp, logaddexp2, fmod)
         raises(TypeError, radians, complex(90,90))
         raises(TypeError, deg2rad, complex(90,90))
         raises(TypeError, degrees, complex(90,90))
         raises(TypeError, rad2deg, complex(90,90))
         raises(TypeError, isneginf, complex(1, 1))
         raises(TypeError, isposinf, complex(1, 1))
+        raises(TypeError, logaddexp, complex(1, 1), complex(3, 3))
+        raises(TypeError, logaddexp2, complex(1, 1), complex(3, 3))
+        raises (TypeError, fmod, complex(90,90), 3) 
 
     def test_isnan_isinf(self):
         from _numpypy import isnan, isinf, array
@@ -287,7 +286,6 @@
                 [False, True, True, False, False]).all()
 
     def test_power_complex(self):
-        import math, cmath
         inf = float('inf')
         ninf = -float('inf')
         nan = float('nan')
@@ -346,20 +344,79 @@
             assert a[1] == b[1]
 
     def test_logn(self):
-        import math
+        import math, cmath
         # log and log10 are tested in math (1:1 from rcomplex)
-        from _numpypy import log2
-        for v in [float('-nan'), float('-inf'), -1, float('nan')]:
-            assert math.isnan(log2(v))
-        for v in [-0.0, 0.0]:
-            assert log2(v) == float("-inf")
-        assert log2(float('inf')) == float('inf')
-        assert (log2([1, 2.]) == [0, 1]).all()
-
+        from _numpypy import log2, array, complex128, complex64, log1p
+        inf = float('inf')
+        ninf = -float('inf')
+        nan = float('nan')
+        cmpl = complex
+        log_2 = math.log(2)
+        a = [cmpl(-5., 0), cmpl(-5., -5.), cmpl(-5., 5.),
+             cmpl(0., -5.), cmpl(0., 0.), cmpl(0., 5.),
+             cmpl(-0., -5.), cmpl(-0., 0.), cmpl(-0., 5.),
+             cmpl(-0., -0.), cmpl(inf, 0.), cmpl(inf, 5.),
+             cmpl(inf, -0.), cmpl(ninf, 0.), cmpl(ninf, 5.),
+             cmpl(ninf, -0.), cmpl(ninf, inf), cmpl(inf, inf),
+             cmpl(ninf, ninf), cmpl(5., inf), cmpl(5., ninf),
+             cmpl(nan, 5.), cmpl(5., nan), cmpl(nan, nan),
+            ]
+        for c,rel_err in ((complex128, 5e-323), (complex64, 1e-7)):
+            b = log2(array(a,dtype=c))
+            got_err = False
+            for i in range(len(a)):
+                try:
+                    _res = cmath.log(a[i])
+                    res = cmpl(_res.real / log_2, _res.imag / log_2)
+                except OverflowError:
+                    res = cmpl(inf, nan)
+                except ValueError:
+                    res = cmpl(ninf, 0)
+                msg = 'result of log2(%r(%r)) got %r expected %r\n ' % \
+                            (c,a[i], b[i], res)
+                try:
+                    # cast untranslated boxed results to float,
+                    # does no harm when translated
+                    t1 = float(res.real)        
+                    t2 = float(b[i].real)        
+                    self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
+                    t1 = float(res.imag)        
+                    t2 = float(b[i].imag)        
+                    self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
+                except AssertionError as e:
+                    print e.message
+                    got_err = True
+        for c,rel_err in ((complex128, 5e-323), (complex64, 1e-7)):
+            b = log1p(array(a,dtype=c))
+            got_err = False
+            for i in range(len(a)):
+                try:
+                    #be careful, normal addition wipes out +-0j
+                    res = cmath.log(cmpl(a[i].real+1, a[i].imag))
+                except OverflowError:
+                    res = cmpl(inf, nan)
+                except ValueError:
+                    res = cmpl(ninf, 0)
+                msg = 'result of log1p(%r(%r)) got %r expected %r\n ' % \
+                            (c,a[i], b[i], res)
+                try:
+                    # cast untranslated boxed results to float,
+                    # does no harm when translated
+                    t1 = float(res.real)        
+                    t2 = float(b[i].real)        
+                    self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
+                    t1 = float(res.imag)        
+                    t2 = float(b[i].imag)        
+                    self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
+                except AssertionError as e:
+                    print e.message
+                    got_err = True
+        if got_err:
+            raise AssertionError('Errors were printed to stdout')
 
     def test_basic(self):
         from _numpypy import (complex128, complex64, add,
-            subtract as sub, multiply, divide, negative, abs, fmod, 
+            subtract as sub, multiply, divide, negative, abs, 
             reciprocal)
         from _numpypy import (equal, not_equal, greater, greater_equal, less,
                 less_equal)
@@ -415,15 +472,11 @@
             assert abs(c0) == 2.5
             assert abs(c2) == 5
             
-            raises (TypeError, fmod, c0, 3) 
             inf_c = complex_(complex(float('inf'), 0.))
             assert repr(abs(inf_c)) == 'inf'
             assert repr(abs(complex(float('nan'), float('nan')))) == 'nan'
-
-        assert False, 'untested: ' + \
-                     'numpy.real. numpy.imag' + \
-                     'log2, log1p, ' + \
-                     'logaddexp, npy_log2_1p, logaddexp2'
+            raises(AttributeError, 'c2.real = 10.')
+            raises(AttributeError, 'c2.imag = 10.')
 
     def test_math(self):
         if self.isWindows:
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -1422,9 +1422,12 @@
             return -rfloat.INFINITY, 0
         return rcomplex.c_log(*v)
 
-    @simple_unary_op
+    @complex_unary_op
     def log2(self, v):
-        return self.log(v) / log2
+        if v[0] == 0 and v[1] == 0:
+            return -rfloat.INFINITY, 0
+        r = rcomplex.c_log(*v)
+        return r[0] / log2, r[1] / log2
 
     @complex_unary_op
     def log10(self, v):
@@ -1432,37 +1435,14 @@
             return -rfloat.INFINITY, 0
         return rcomplex.c_log10(*v)
 
-    @simple_unary_op
+    @complex_unary_op
     def log1p(self, v):
         try:
-            return rfloat.log1p(v)
+            return rcomplex.c_log(v[0]+1, v[1])
         except OverflowError:
-            return -rfloat.INFINITY
+            return -rfloat.INFINITY, 0
         except ValueError:
-            return rfloat.NAN
-
-    @simple_binary_op
-    def logaddexp(self, v1, v2):
-        tmp = v1 - v2
-        if tmp > 0:
-            return v1 + rfloat.log1p(math.exp(-tmp))
-        elif tmp <= 0:
-            return v2 + rfloat.log1p(math.exp(tmp))
-        else:
-            return v1 + v2
-
-    def npy_log2_1p(self, v):
-        return log2e * rfloat.log1p(v)
-
-    @simple_binary_op
-    def logaddexp2(self, v1, v2):
-        tmp = v1 - v2
-        if tmp > 0:
-            return v1 + self.npy_log2_1p(math.pow(2, -tmp))
-        if tmp <= 0:
-            return v2 + self.npy_log2_1p(math.pow(2, tmp))
-        else:
-            return v1 + v2
+            return rfloat.NAN, rfloat.NAN
 
 class Complex64(ComplexFloating, BaseType):
     _attrs_ = ()


More information about the pypy-commit mailing list