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