PageRenderTime 45ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/module/cmath/test/test_cmath.py

https://bitbucket.org/pypy/pypy/
Python | 241 lines | 213 code | 22 blank | 6 comment | 7 complexity | 3fe9ff6c3979fdebf0ff11d9e2f3ab0d MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from __future__ import with_statement
  2. from rpython.rlib.rfloat import copysign, isnan, isinf
  3. from pypy.module.cmath import interp_cmath
  4. import os, sys, math
  5. def test_special_values():
  6. from rpython.rlib.special_value import sqrt_special_values
  7. assert len(sqrt_special_values) == 7
  8. assert len(sqrt_special_values[4]) == 7
  9. assert isinstance(sqrt_special_values[5][1], tuple)
  10. assert sqrt_special_values[5][1][0] == 1e200 * 1e200
  11. assert sqrt_special_values[5][1][1] == -0.
  12. assert copysign(1., sqrt_special_values[5][1][1]) == -1.
  13. class AppTestCMath:
  14. spaceconfig = dict(usemodules=['cmath'])
  15. def test_sign(self):
  16. import math
  17. z = eval("-0j")
  18. assert z == -0j
  19. assert math.copysign(1., z.real) == 1.
  20. assert math.copysign(1., z.imag) == -1.
  21. def test_sqrt(self):
  22. import cmath, math
  23. assert cmath.sqrt(3+4j) == 2+1j
  24. z = cmath.sqrt(-0j)
  25. assert math.copysign(1., z.real) == 1.
  26. assert math.copysign(1., z.imag) == -1.
  27. dbl_min = 2.2250738585072014e-308
  28. z = cmath.sqrt((dbl_min * 0.00000000000001) + 0j)
  29. assert abs(z.real - 1.49107189843e-161) < 1e-170
  30. assert z.imag == 0.0
  31. z = cmath.sqrt(1e200*1e200 - 10j)
  32. assert math.isinf(z.real) and z.real > 0.0
  33. assert z.imag == 0.0 and math.copysign(1., z.imag) == -1.
  34. def test_log(self):
  35. import cmath, math
  36. z = cmath.log(100j, 10j)
  37. assert abs(z - (1.6824165174565446-0.46553647994440367j)) < 1e-10
  38. def test_pi_e(self):
  39. import cmath, math
  40. assert cmath.pi == math.pi
  41. assert cmath.e == math.e
  42. def test_rect(self):
  43. import cmath
  44. z = cmath.rect(2.0, cmath.pi/2)
  45. assert abs(z - 2j) < 1e-10
  46. def test_polar(self):
  47. import cmath
  48. r, phi = cmath.polar(2j)
  49. assert r == 2
  50. assert abs(phi - cmath.pi/2) < 1e-10
  51. def test_phase(self):
  52. import cmath
  53. phi = cmath.phase(2j)
  54. assert abs(phi - cmath.pi/2) < 1e-10
  55. def test_valueerror(self):
  56. import cmath
  57. raises(ValueError, cmath.log, 0j)
  58. def test_stringarg(self):
  59. import cmath
  60. raises(TypeError, cmath.log, "-3j")
  61. def test_isinf(self):
  62. import cmath
  63. assert not cmath.isinf(2+3j)
  64. assert cmath.isinf(float("inf"))
  65. assert cmath.isinf(-float("inf"))
  66. assert cmath.isinf(complex("infj"))
  67. assert cmath.isinf(complex("2-infj"))
  68. assert cmath.isinf(complex("inf+nanj"))
  69. assert cmath.isinf(complex("nan+infj"))
  70. def test_isnan(self):
  71. import cmath
  72. assert not cmath.isnan(2+3j)
  73. assert cmath.isnan(float("nan"))
  74. assert cmath.isnan(complex("nanj"))
  75. assert cmath.isnan(complex("inf+nanj"))
  76. assert cmath.isnan(complex("nan+infj"))
  77. def test_user_defined_complex(self):
  78. import cmath
  79. class Foo(object):
  80. def __complex__(self):
  81. return 2j
  82. r, phi = cmath.polar(Foo())
  83. assert r == 2
  84. assert abs(phi - cmath.pi/2) < 1e-10
  85. def test_user_defined_float(self):
  86. import cmath
  87. class Foo(object):
  88. def __float__(self):
  89. return 2.0
  90. assert cmath.polar(Foo()) == (2, 0)
  91. def parse_testfile(fname):
  92. """Parse a file with test values
  93. Empty lines or lines starting with -- are ignored
  94. yields id, fn, arg_real, arg_imag, exp_real, exp_imag
  95. """
  96. with open(fname) as fp:
  97. for line in fp:
  98. # skip comment lines and blank lines
  99. if line.startswith('--') or not line.strip():
  100. continue
  101. lhs, rhs = line.split('->')
  102. id, fn, arg_real, arg_imag = lhs.split()
  103. rhs_pieces = rhs.split()
  104. exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1]
  105. flags = rhs_pieces[2:]
  106. yield (id, fn,
  107. float(arg_real), float(arg_imag),
  108. float(exp_real), float(exp_imag),
  109. flags
  110. )
  111. def rAssertAlmostEqual(a, b, rel_err = 2e-15, abs_err = 5e-323, msg=''):
  112. """Fail if the two floating-point numbers are not almost equal.
  113. Determine whether floating-point values a and b are equal to within
  114. a (small) rounding error. The default values for rel_err and
  115. abs_err are chosen to be suitable for platforms where a float is
  116. represented by an IEEE 754 double. They allow an error of between
  117. 9 and 19 ulps.
  118. """
  119. # special values testing
  120. if isnan(a):
  121. if isnan(b):
  122. return
  123. raise AssertionError(msg + '%r should be nan' % (b,))
  124. if isinf(a):
  125. if a == b:
  126. return
  127. raise AssertionError(msg + 'finite result where infinity expected: '
  128. 'expected %r, got %r' % (a, b))
  129. # if both a and b are zero, check whether they have the same sign
  130. # (in theory there are examples where it would be legitimate for a
  131. # and b to have opposite signs; in practice these hardly ever
  132. # occur).
  133. if not a and not b:
  134. # only check it if we are running on top of CPython >= 2.6
  135. if sys.version_info >= (2, 6) and copysign(1., a) != copysign(1., b):
  136. raise AssertionError(msg + 'zero has wrong sign: expected %r, '
  137. 'got %r' % (a, b))
  138. # if a-b overflows, or b is infinite, return False. Again, in
  139. # theory there are examples where a is within a few ulps of the
  140. # max representable float, and then b could legitimately be
  141. # infinite. In practice these examples are rare.
  142. try:
  143. absolute_error = abs(b-a)
  144. except OverflowError:
  145. pass
  146. else:
  147. # test passes if either the absolute error or the relative
  148. # error is sufficiently small. The defaults amount to an
  149. # error of between 9 ulps and 19 ulps on an IEEE-754 compliant
  150. # machine.
  151. if absolute_error <= max(abs_err, rel_err * abs(a)):
  152. return
  153. raise AssertionError(msg + '%r and %r are not sufficiently close' % (a, b))
  154. def test_specific_values():
  155. #if not float.__getformat__("double").startswith("IEEE"):
  156. # return
  157. import rpython
  158. # too fragile...
  159. fname = os.path.join(os.path.dirname(rpython.rlib.__file__), 'test', 'rcomplex_testcases.txt')
  160. for id, fn, ar, ai, er, ei, flags in parse_testfile(fname):
  161. arg = (ar, ai)
  162. expected = (er, ei)
  163. function = getattr(interp_cmath, 'c_' + fn)
  164. #
  165. if 'divide-by-zero' in flags or 'invalid' in flags:
  166. try:
  167. actual = function(*arg)
  168. except ValueError:
  169. continue
  170. else:
  171. raise AssertionError('ValueError not raised in test '
  172. '%s: %s(complex(%r, %r))' % (id, fn,
  173. ar, ai))
  174. if 'overflow' in flags:
  175. try:
  176. actual = function(*arg)
  177. except OverflowError:
  178. continue
  179. else:
  180. raise AssertionError('OverflowError not raised in test '
  181. '%s: %s(complex(%r, %r))' % (id, fn,
  182. ar, ai))
  183. actual = function(*arg)
  184. if 'ignore-real-sign' in flags:
  185. actual = (abs(actual[0]), actual[1])
  186. expected = (abs(expected[0]), expected[1])
  187. if 'ignore-imag-sign' in flags:
  188. actual = (actual[0], abs(actual[1]))
  189. expected = (expected[0], abs(expected[1]))
  190. # for the real part of the log function, we allow an
  191. # absolute error of up to 2e-15.
  192. if fn in ('log', 'log10'):
  193. real_abs_err = 2e-15
  194. else:
  195. real_abs_err = 5e-323
  196. error_message = (
  197. '%s: %s(complex(%r, %r))\n'
  198. 'Expected: complex(%r, %r)\n'
  199. 'Received: complex(%r, %r)\n'
  200. ) % (id, fn, ar, ai,
  201. expected[0], expected[1],
  202. actual[0], actual[1])
  203. rAssertAlmostEqual(expected[0], actual[0],
  204. abs_err=real_abs_err,
  205. msg=error_message)
  206. rAssertAlmostEqual(expected[1], actual[1],
  207. msg=error_message)