Author: mattip <[email protected]>
Branch: numpypy-complex2
Changeset: r56918:76cd8e4de63a
Date: 2012-08-28 23:41 +0300
http://bitbucket.org/pypy/pypy/changeset/76cd8e4de63a/

Log:    add module/cmath tests to rlib/rcomplex

diff --git a/pypy/module/cmath/interp_cmath.py 
b/pypy/module/cmath/interp_cmath.py
--- a/pypy/module/cmath/interp_cmath.py
+++ b/pypy/module/cmath/interp_cmath.py
@@ -6,23 +6,23 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.gateway import NoneNotWrapped
 from pypy.module.cmath import names_and_docstrings
-from pypy.module.cmath.constant import DBL_MIN, CM_SCALE_UP, CM_SCALE_DOWN
-from pypy.module.cmath.constant import CM_LARGE_DOUBLE, DBL_MANT_DIG
-from pypy.module.cmath.constant import M_LN2, M_LN10
-from pypy.module.cmath.constant import CM_SQRT_LARGE_DOUBLE, CM_SQRT_DBL_MIN
-from pypy.module.cmath.constant import CM_LOG_LARGE_DOUBLE
-from pypy.module.cmath.special_value import isfinite, special_type, INF, NAN
-from pypy.module.cmath.special_value import sqrt_special_values
-from pypy.module.cmath.special_value import acos_special_values
-from pypy.module.cmath.special_value import acosh_special_values
-from pypy.module.cmath.special_value import asinh_special_values
-from pypy.module.cmath.special_value import atanh_special_values
-from pypy.module.cmath.special_value import log_special_values
-from pypy.module.cmath.special_value import exp_special_values
-from pypy.module.cmath.special_value import cosh_special_values
-from pypy.module.cmath.special_value import sinh_special_values
-from pypy.module.cmath.special_value import tanh_special_values
-from pypy.module.cmath.special_value import rect_special_values
+from pypy.rlib.constant import DBL_MIN, CM_SCALE_UP, CM_SCALE_DOWN
+from pypy.rlib.constant import CM_LARGE_DOUBLE, DBL_MANT_DIG
+from pypy.rlib.constant import M_LN2, M_LN10
+from pypy.rlib.constant import CM_SQRT_LARGE_DOUBLE, CM_SQRT_DBL_MIN
+from pypy.rlib.constant import CM_LOG_LARGE_DOUBLE
+from pypy.rlib.special_value import isfinite, special_type, INF, NAN
+from pypy.rlib.special_value import sqrt_special_values
+from pypy.rlib.special_value import acos_special_values
+from pypy.rlib.special_value import acosh_special_values
+from pypy.rlib.special_value import asinh_special_values
+from pypy.rlib.special_value import atanh_special_values
+from pypy.rlib.special_value import log_special_values
+from pypy.rlib.special_value import exp_special_values
+from pypy.rlib.special_value import cosh_special_values
+from pypy.rlib.special_value import sinh_special_values
+from pypy.rlib.special_value import tanh_special_values
+from pypy.rlib.special_value import rect_special_values
 
 pi = math.pi
 e  = math.e
diff --git a/pypy/module/cmath/test/test_cmath.py 
b/pypy/module/cmath/test/test_cmath.py
--- a/pypy/module/cmath/test/test_cmath.py
+++ b/pypy/module/cmath/test/test_cmath.py
@@ -6,7 +6,7 @@
 
 
 def test_special_values():
-    from pypy.module.cmath.special_value import sqrt_special_values
+    from pypy.rlib.special_value import sqrt_special_values
     assert len(sqrt_special_values) == 7
     assert len(sqrt_special_values[4]) == 7
     assert isinstance(sqrt_special_values[5][1], tuple)
diff --git a/pypy/module/cmath/constant.py b/pypy/rlib/constant.py
rename from pypy/module/cmath/constant.py
rename to pypy/rlib/constant.py
diff --git a/pypy/rlib/rcomplex.py b/pypy/rlib/rcomplex.py
--- a/pypy/rlib/rcomplex.py
+++ b/pypy/rlib/rcomplex.py
@@ -1,9 +1,22 @@
 import math
-from math import copysign, fabs
-from pypy.module.cmath.special_value import (isfinite, sqrt_special_values,
-        cosh_special_values, sinh_special_values, exp_special_values,
-        special_type, )
-from pypy.rlib.rfloat import INFINITE as INF, NAN, isinf, DBL_MIN
+from math import copysign, fabs, pi, e
+from pypy.rlib.constant import DBL_MIN, CM_SCALE_UP, CM_SCALE_DOWN
+from pypy.rlib.constant import CM_LARGE_DOUBLE, DBL_MANT_DIG
+from pypy.rlib.constant import M_LN2, M_LN10
+from pypy.rlib.constant import CM_SQRT_LARGE_DOUBLE, CM_SQRT_DBL_MIN
+from pypy.rlib.constant import CM_LOG_LARGE_DOUBLE
+from pypy.rlib.special_value import isfinite, special_type, INF, NAN
+from pypy.rlib.special_value import sqrt_special_values
+from pypy.rlib.special_value import acos_special_values
+from pypy.rlib.special_value import acosh_special_values
+from pypy.rlib.special_value import asinh_special_values
+from pypy.rlib.special_value import atanh_special_values
+from pypy.rlib.special_value import log_special_values
+from pypy.rlib.special_value import exp_special_values
+from pypy.rlib.special_value import cosh_special_values
+from pypy.rlib.special_value import sinh_special_values
+from pypy.rlib.special_value import tanh_special_values
+from pypy.rlib.special_value import rect_special_values
 
 #binary
 
diff --git a/pypy/module/cmath/special_value.py b/pypy/rlib/special_value.py
rename from pypy/module/cmath/special_value.py
rename to pypy/rlib/special_value.py
diff --git a/pypy/module/cmath/test/cmath_testcases.txt 
b/pypy/rlib/test/rcomplex_testcases.txt
copy from pypy/module/cmath/test/cmath_testcases.txt
copy to pypy/rlib/test/rcomplex_testcases.txt
diff --git a/pypy/rlib/test/test_rcomplex.py b/pypy/rlib/test/test_rcomplex.py
--- a/pypy/rlib/test/test_rcomplex.py
+++ b/pypy/rlib/test/test_rcomplex.py
@@ -1,5 +1,8 @@
+from __future__ import with_statement
 
 import pypy.rlib.rcomplex as c
+from pypy.rlib.rfloat import copysign, isnan, isinf
+import os, sys, math
 
 
 def test_add():
@@ -28,4 +31,135 @@
             ((0, 3), (0, 2), (-6, 0)),
             ((0, -3), (-5, 0), (0, 15)),
         ]:
-            assert c.c_mul(c1, c2) == result
\ No newline at end of file
+            assert c.c_mul(c1, c2) == result
+
+def parse_testfile(fname):
+    """Parse a file with test values
+
+    Empty lines or lines starting with -- are ignored
+    yields id, fn, arg_real, arg_imag, exp_real, exp_imag
+    """
+    fname = os.path.join(os.path.dirname(__file__), fname)
+    with open(fname) as fp:
+        for line in fp:
+            # skip comment lines and blank lines
+            if line.startswith('--') or not line.strip():
+                continue
+
+            lhs, rhs = line.split('->')
+            id, fn, arg_real, arg_imag = lhs.split()
+            rhs_pieces = rhs.split()
+            exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1]
+            flags = rhs_pieces[2:]
+
+            yield (id, fn,
+                   float(arg_real), float(arg_imag),
+                   float(exp_real), float(exp_imag),
+                   flags
+                  )
+
+def rAssertAlmostEqual(a, b, rel_err = 2e-15, abs_err = 5e-323, msg=''):
+    """Fail if the two floating-point numbers are not almost equal.
+
+    Determine whether floating-point values a and b are equal to within
+    a (small) rounding error.  The default values for rel_err and
+    abs_err are chosen to be suitable for platforms where a float is
+    represented by an IEEE 754 double.  They allow an error of between
+    9 and 19 ulps.
+    """
+
+    # special values testing
+    if isnan(a):
+        if isnan(b):
+            return
+        raise AssertionError(msg + '%r should be nan' % (b,))
+
+    if isinf(a):
+        if a == b:
+            return
+        raise AssertionError(msg + 'finite result where infinity expected: '
+                                   'expected %r, got %r' % (a, b))
+
+    # if both a and b are zero, check whether they have the same sign
+    # (in theory there are examples where it would be legitimate for a
+    # and b to have opposite signs; in practice these hardly ever
+    # occur).
+    if not a and not b:
+        # only check it if we are running on top of CPython >= 2.6
+        if sys.version_info >= (2, 6) and copysign(1., a) != copysign(1., b):
+            raise AssertionError(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
+    # max representable float, and then b could legitimately be
+    # infinite.  In practice these examples are rare.
+    try:
+        absolute_error = abs(b-a)
+    except OverflowError:
+        pass
+    else:
+        # test passes if either the absolute error or the relative
+        # error is sufficiently small.  The defaults amount to an
+        # error of between 9 ulps and 19 ulps on an IEEE-754 compliant
+        # machine.
+        if absolute_error <= max(abs_err, rel_err * abs(a)):
+            return
+    raise AssertionError(msg + '%r and %r are not sufficiently close' % (a, b))
+
+def test_specific_values():
+    #if not float.__getformat__("double").startswith("IEEE"):
+    #    return
+
+    for id, fn, ar, ai, er, ei, flags in 
parse_testfile('rcomplex_testcases.txt'):
+        arg = (ar, ai)
+        expected = (er, ei)
+        function = getattr(c, 'c_' + fn)
+        #
+        if 'divide-by-zero' in flags or 'invalid' in flags:
+            try:
+                actual = function(*arg)
+            except ValueError:
+                continue
+            else:
+                raise AssertionError('ValueError not raised in test '
+                                     '%s: %s(complex(%r, %r))' % (id, fn,
+                                                                  ar, ai))
+        if 'overflow' in flags:
+            try:
+                actual = function(*arg)
+            except OverflowError:
+                continue
+            else:
+                raise AssertionError('OverflowError not raised in test '
+                                     '%s: %s(complex(%r, %r))' % (id, fn,
+                                                                  ar, ai))
+        actual = function(*arg)
+
+        if 'ignore-real-sign' in flags:
+            actual = (abs(actual[0]), actual[1])
+            expected = (abs(expected[0]), expected[1])
+        if 'ignore-imag-sign' in flags:
+            actual = (actual[0], abs(actual[1]))
+            expected = (expected[0], abs(expected[1]))
+
+        # for the real part of the log function, we allow an
+        # absolute error of up to 2e-15.
+        if fn in ('log', 'log10'):
+            real_abs_err = 2e-15
+        else:
+            real_abs_err = 5e-323
+
+        error_message = (
+            '%s: %s(complex(%r, %r))\n'
+            'Expected: complex(%r, %r)\n'
+            'Received: complex(%r, %r)\n'
+            ) % (id, fn, ar, ai,
+                 expected[0], expected[1],
+                 actual[0], actual[1])
+
+        rAssertAlmostEqual(expected[0], actual[0],
+                           abs_err=real_abs_err,
+                           msg=error_message)
+        rAssertAlmostEqual(expected[1], actual[1],
+                           msg=error_message)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to