[pypy-commit] pypy numpypy-complex2: (fijal, arigo)
arigo
noreply at buildbot.pypy.org
Mon Oct 8 13:47:34 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: numpypy-complex2
Changeset: r57902:3acbfe0aaf8b
Date: 2012-10-08 13:47 +0200
http://bitbucket.org/pypy/pypy/changeset/3acbfe0aaf8b/
Log: (fijal, arigo)
- speed up test_complex
- Python 2.5 compatibility
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
@@ -1,6 +1,7 @@
+from __future__ import with_statement
+import sys
from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest
-from math import isnan, isinf, copysign
-from sys import version_info, builtin_module_names
+from pypy.rlib.rfloat import isnan, isinf, copysign
from pypy.rlib.rcomplex import c_pow
from pypy.interpreter.error import OperationError
@@ -34,7 +35,7 @@
# occur).
if not a and not b and not isnumpy:
# 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):
+ 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))
@@ -57,26 +58,50 @@
'%r and %r are not sufficiently close, %g > %g' %\
(a, b, absolute_error, max(abs_err, rel_err*abs(a))))
+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
+ """
+ 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
+ )
+
class AppTestUfuncs(BaseNumpyAppTest):
def setup_class(cls):
import os
BaseNumpyAppTest.setup_class.im_func(cls)
fname128 = os.path.join(os.path.dirname(__file__), 'complex_testcases.txt')
fname64 = os.path.join(os.path.dirname(__file__), 'complex64_testcases.txt')
- cls.w_testcases128 = cls.space.wrap(fname128)
- cls.w_testcases64 = cls.space.wrap(fname64)
+ cls.w_testcases128 = cls.space.wrap(list(parse_testfile(fname128)))
+ cls.w_testcases64 = cls.space.wrap(list(parse_testfile(fname64)))
def cls_c_pow(self, *args):
try:
retVal = c_pow(*args)
return retVal
- except ValueError as e:
+ except ValueError, e:
raise OperationError(cls.space.w_ValueError,
cls.space.wrap(e.message))
cls.w_c_pow = cls.space.wrap(cls_c_pow)
cls.w_runAppDirect = cls.space.wrap(option.runappdirect)
cls.w_isWindows = cls.space.wrap(os.name == 'nt')
def cls_rAlmostEqual(self, *args, **kwargs):
- if '__pypy__' not in builtin_module_names:
+ if '__pypy__' not in sys.builtin_module_names:
kwargs['isnumpy'] = True
return rAlmostEqual(*args, **kwargs)
cls.w_rAlmostEqual = cls.space.wrap(cls_rAlmostEqual)
@@ -237,7 +262,6 @@
cmpl(nan, 5.), cmpl(5., nan), cmpl(nan, nan),
]
b = expm1(array(a,dtype=c))
- got_err = False
for i in range(len(a)):
try:
res = cmath.exp(a[i]) - 1.
@@ -251,20 +275,14 @@
res = cmpl(nan, nan)
msg = 'result of expm1(%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')
+ # 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)
def test_not_complex(self):
from _numpypy import (radians, deg2rad, degrees, rad2deg,
@@ -315,7 +333,6 @@
cmpl(ninf, ninf), cmpl(5., inf), cmpl(5., ninf),
cmpl(nan, 5.), cmpl(5., nan), cmpl(nan, nan),
], dtype=c)
- got_err = False
for p in (3, -1, 10000, 2.3, -10000, 10+3j):
b = power(a, p)
for i in range(len(a)):
@@ -330,18 +347,12 @@
r = (nan, nan)
msg = 'result of %r(%r)**%r got %r expected %r\n ' % \
(c,a[i], p, b[i], r)
- try:
- t1 = float(r[0])
- t2 = float(b[i].real)
- self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
- t1 = float(r[1])
- 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')
+ t1 = float(r[0])
+ t2 = float(b[i].real)
+ self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
+ t1 = float(r[1])
+ t2 = float(b[i].imag)
+ self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
def test_conjugate(self):
from _numpypy import conj, conjugate, complex128, complex64
@@ -385,7 +396,6 @@
]
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])
@@ -396,21 +406,16 @@
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
+ # 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)
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
@@ -421,20 +426,14 @@
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')
+ # 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)
def test_logical_ops(self):
from _numpypy import logical_and, logical_or, logical_xor, logical_not
@@ -540,37 +539,15 @@
def test_math(self):
if self.isWindows:
skip('windows does not support c99 complex')
- import _numpypy as np
+ import sys
+ import _numpypy as np
rAlmostEqual = self.rAlmostEqual
- 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
- """
- 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
- )
for complex_, abs_err, testcases in (\
(np.complex128, 5e-323, self.testcases128),
# (np.complex64, 5e-32, self.testcases64),
):
- for id, fn, ar, ai, er, ei, flags in parse_testfile(testcases):
+ for id, fn, ar, ai, er, ei, flags in testcases:
arg = complex_(complex(ar, ai))
expected = (er, ei)
if fn.startswith('acos'):
@@ -613,5 +590,5 @@
abs_err=real_abs_err, msg=error_message)
rAlmostEqual(float(expected[1]), float(actual[1]),
msg=error_message)
-
-
+ sys.stderr.write('.')
+ sys.stderr.write('\n')
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
@@ -23,7 +23,7 @@
log2e = 1. / log2
def isfinite(d):
- return not math.isinf(d) and not math.isnan(d)
+ return not rfloat.isinf(d) and not rfloat.isnan(d)
def simple_unary_op(func):
specialize.argtype(1)(func)
@@ -671,17 +671,17 @@
@simple_binary_op
def fmax(self, v1, v2):
- if math.isnan(v2):
+ if rfloat.isnan(v2):
return v1
- elif math.isnan(v1):
+ elif rfloat.isnan(v1):
return v2
return max(v1, v2)
@simple_binary_op
def fmin(self, v1, v2):
- if math.isnan(v2):
+ if rfloat.isnan(v2):
return v1
- elif math.isnan(v1):
+ elif rfloat.isnan(v1):
return v2
return min(v1, v2)
@@ -1219,9 +1219,9 @@
@complex_unary_op
def reciprocal(self, v):
- if math.isinf(v[1]) and math.isinf(v[0]):
+ if rfloat.isinf(v[1]) and rfloat.isinf(v[0]):
return rfloat.NAN, rfloat.NAN
- if math.isinf(v[0]):
+ if rfloat.isinf(v[0]):
return (rfloat.copysign(0., v[0]),
rfloat.copysign(0., -v[1]))
a2 = v[0]*v[0] + v[1]*v[1]
@@ -1248,13 +1248,13 @@
@complex_unary_op
def exp(self, v):
- if math.isinf(v[1]):
- if math.isinf(v[0]):
+ if rfloat.isinf(v[1]):
+ if rfloat.isinf(v[0]):
if v[0] < 0:
return 0., 0.
return rfloat.INFINITY, rfloat.NAN
elif (isfinite(v[0]) or \
- (math.isinf(v[0]) and v[0] > 0)):
+ (rfloat.isinf(v[0]) and v[0] > 0)):
return rfloat.NAN, rfloat.NAN
try:
return rcomplex.c_exp(*v)
@@ -1276,13 +1276,13 @@
def expm1(self, v):
#Duplicate exp() so in the future it will be easier
# to implement seterr
- if math.isinf(v[1]):
- if math.isinf(v[0]):
+ if rfloat.isinf(v[1]):
+ if rfloat.isinf(v[0]):
if v[0] < 0:
return -1., 0.
return rfloat.NAN, rfloat.NAN
elif (isfinite(v[0]) or \
- (math.isinf(v[0]) and v[0] > 0)):
+ (rfloat.isinf(v[0]) and v[0] > 0)):
return rfloat.NAN, rfloat.NAN
try:
res = rcomplex.c_exp(*v)
@@ -1295,29 +1295,29 @@
@complex_unary_op
def sin(self, v):
- if math.isinf(v[0]):
+ if rfloat.isinf(v[0]):
if v[1] == 0.:
return rfloat.NAN, 0.
if isfinite(v[1]):
return rfloat.NAN, rfloat.NAN
- elif not math.isnan(v[1]):
+ elif not rfloat.isnan(v[1]):
return rfloat.NAN, rfloat.INFINITY
return rcomplex.c_sin(*v)
@complex_unary_op
def cos(self, v):
- if math.isinf(v[0]):
+ if rfloat.isinf(v[0]):
if v[1] == 0.:
return rfloat.NAN, 0.0
if isfinite(v[1]):
return rfloat.NAN, rfloat.NAN
- elif not math.isnan(v[1]):
+ elif not rfloat.isnan(v[1]):
return rfloat.INFINITY, rfloat.NAN
return rcomplex.c_cos(*v)
@complex_unary_op
def tan(self, v):
- if math.isinf(v[0]) and isfinite(v[1]):
+ if rfloat.isinf(v[0]) and isfinite(v[1]):
return rfloat.NAN, rfloat.NAN
return rcomplex.c_tan(*v)
@@ -1342,29 +1342,29 @@
@complex_unary_op
def sinh(self, v):
- if math.isinf(v[1]):
+ if rfloat.isinf(v[1]):
if isfinite(v[0]):
if v[0] == 0.0:
return 0.0, rfloat.NAN
return rfloat.NAN, rfloat.NAN
- elif not math.isnan(v[0]):
+ elif not rfloat.isnan(v[0]):
return rfloat.INFINITY, rfloat.NAN
return rcomplex.c_sinh(*v)
@complex_unary_op
def cosh(self, v):
- if math.isinf(v[1]):
+ if rfloat.isinf(v[1]):
if isfinite(v[0]):
if v[0] == 0.0:
return rfloat.NAN, 0.0
return rfloat.NAN, rfloat.NAN
- elif not math.isnan(v[0]):
+ elif not rfloat.isnan(v[0]):
return rfloat.INFINITY, rfloat.NAN
return rcomplex.c_cosh(*v)
@complex_unary_op
def tanh(self, v):
- if math.isinf(v[1]) and isfinite(v[0]):
+ if rfloat.isinf(v[1]) and isfinite(v[0]):
return rfloat.NAN, rfloat.NAN
return rcomplex.c_tanh(*v)
diff --git a/pypy/rlib/rcomplex.py b/pypy/rlib/rcomplex.py
--- a/pypy/rlib/rcomplex.py
+++ b/pypy/rlib/rcomplex.py
@@ -1,5 +1,5 @@
import math
-from math import copysign, fabs, pi, e
+from math import fabs, pi, e
from pypy.rlib.rfloat import copysign, asinh, log1p, isinf, isnan
from pypy.rlib.constant import DBL_MIN, CM_SCALE_UP, CM_SCALE_DOWN
from pypy.rlib.constant import CM_LARGE_DOUBLE, DBL_MANT_DIG
More information about the pypy-commit
mailing list