[pypy-commit] pypy default: Adding log, log2, log10, log1p functions to numpypy

taavi_burns noreply at buildbot.pypy.org
Mon Mar 12 22:38:46 CET 2012


Author: Taavi Burns <taavi.burns at gmail.com>
Branch: 
Changeset: r53352:bfea598edce9
Date: 2012-03-12 14:21 -0700
http://bitbucket.org/pypy/pypy/changeset/bfea598edce9/

Log:	Adding log, log2, log10, log1p functions to numpypy

diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -107,6 +107,10 @@
         ('logical_xor', 'logical_xor'),
         ('logical_not', 'logical_not'),
         ('logical_or', 'logical_or'),
+        ('log', 'log'),
+        ('log2', 'log2'),
+        ('log10', 'log10'),
+        ('log1p', 'log1p'),
     ]:
         interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl
 
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
@@ -441,6 +441,11 @@
             ("arcsinh", "arcsinh", 1, {"promote_to_float": True}),
             ("arccosh", "arccosh", 1, {"promote_to_float": True}),
             ("arctanh", "arctanh", 1, {"promote_to_float": True}),
+
+            ("log", "log", 1, {"promote_to_float": True}),
+            ("log2", "log2", 1, {"promote_to_float": True}),
+            ("log10", "log10", 1, {"promote_to_float": True}),
+            ("log1p", "log1p", 1, {"promote_to_float": True}),
         ]:
             self.add_ufunc(space, *ufunc_def)
 
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -481,3 +481,26 @@
         assert (logical_xor([True, False, True, False], [1, 2, 0, 0])
                 == [False, True, True, False]).all()
         assert (logical_not([True, False]) == [False, True]).all()
+
+    def test_logn(self):
+        import math
+        from _numpypy import log, log2, log10
+
+        for log_func, base in [(log, math.e), (log2, 2), (log10, 10)]:
+            for v in [float('-nan'), float('-inf'), -1, float('nan')]:
+                assert math.isnan(log_func(v))
+            for v in [-0.0, 0.0]:
+                assert log_func(v) == float("-inf")
+            assert log_func(float('inf')) == float('inf')
+            assert (log_func([1, base]) == [0, 1]).all()
+
+    def test_log1p(self):
+        import math
+        from _numpypy import log1p
+
+        for v in [float('-nan'), float('-inf'), -2, float('nan')]:
+            assert math.isnan(log1p(v))
+        for v in [-1]:
+            assert log1p(v) == float("-inf")
+        assert log1p(float('inf')) == float('inf')
+        assert (log1p([0, 1e-50, math.e - 1]) == [0, 1e-50, 1]).all()
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
@@ -533,6 +533,48 @@
     def isinf(self, v):
         return rfloat.isinf(v)
 
+    @simple_unary_op
+    def log(self, v):
+        try:
+            return math.log(v)
+        except ValueError:
+            if v == 0.0:
+                # CPython raises ValueError here, so we have to check
+                # the value to find the correct numpy return value
+                return -rfloat.INFINITY
+            return rfloat.NAN
+
+    @simple_unary_op
+    def log2(self, v):
+        try:
+            return math.log(v, 2)
+        except ValueError:
+            if v == 0.0:
+                # CPython raises ValueError here, so we have to check
+                # the value to find the correct numpy return value
+                return -rfloat.INFINITY
+            return rfloat.NAN
+
+    @simple_unary_op
+    def log10(self, v):
+        try:
+            return math.log10(v)
+        except ValueError:
+            if v == 0.0:
+                # CPython raises ValueError here, so we have to check
+                # the value to find the correct numpy return value
+                return -rfloat.INFINITY
+            return rfloat.NAN
+
+    @simple_unary_op
+    def log1p(self, v):
+        try:
+            return rfloat.log1p(v)
+        except OverflowError:
+            return -rfloat.INFINITY
+        except ValueError:
+            return rfloat.NAN
+
 
 class Float32(BaseType, Float):
     T = rffi.FLOAT


More information about the pypy-commit mailing list