test_cmath.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. from test.support import requires_IEEE_754, cpython_only, import_helper
  2. from test.test_math import parse_testfile, test_file
  3. import test.test_math as test_math
  4. import unittest
  5. import cmath, math
  6. from cmath import phase, polar, rect, pi
  7. import platform
  8. import sys
  9. INF = float('inf')
  10. NAN = float('nan')
  11. complex_zeros = [complex(x, y) for x in [0.0, -0.0] for y in [0.0, -0.0]]
  12. complex_infinities = [complex(x, y) for x, y in [
  13. (INF, 0.0), # 1st quadrant
  14. (INF, 2.3),
  15. (INF, INF),
  16. (2.3, INF),
  17. (0.0, INF),
  18. (-0.0, INF), # 2nd quadrant
  19. (-2.3, INF),
  20. (-INF, INF),
  21. (-INF, 2.3),
  22. (-INF, 0.0),
  23. (-INF, -0.0), # 3rd quadrant
  24. (-INF, -2.3),
  25. (-INF, -INF),
  26. (-2.3, -INF),
  27. (-0.0, -INF),
  28. (0.0, -INF), # 4th quadrant
  29. (2.3, -INF),
  30. (INF, -INF),
  31. (INF, -2.3),
  32. (INF, -0.0)
  33. ]]
  34. complex_nans = [complex(x, y) for x, y in [
  35. (NAN, -INF),
  36. (NAN, -2.3),
  37. (NAN, -0.0),
  38. (NAN, 0.0),
  39. (NAN, 2.3),
  40. (NAN, INF),
  41. (-INF, NAN),
  42. (-2.3, NAN),
  43. (-0.0, NAN),
  44. (0.0, NAN),
  45. (2.3, NAN),
  46. (INF, NAN)
  47. ]]
  48. class CMathTests(unittest.TestCase):
  49. # list of all functions in cmath
  50. test_functions = [getattr(cmath, fname) for fname in [
  51. 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh',
  52. 'cos', 'cosh', 'exp', 'log', 'log10', 'sin', 'sinh',
  53. 'sqrt', 'tan', 'tanh']]
  54. # test first and second arguments independently for 2-argument log
  55. test_functions.append(lambda x : cmath.log(x, 1729. + 0j))
  56. test_functions.append(lambda x : cmath.log(14.-27j, x))
  57. def setUp(self):
  58. self.test_values = open(test_file, encoding="utf-8")
  59. def tearDown(self):
  60. self.test_values.close()
  61. def assertFloatIdentical(self, x, y):
  62. """Fail unless floats x and y are identical, in the sense that:
  63. (1) both x and y are nans, or
  64. (2) both x and y are infinities, with the same sign, or
  65. (3) both x and y are zeros, with the same sign, or
  66. (4) x and y are both finite and nonzero, and x == y
  67. """
  68. msg = 'floats {!r} and {!r} are not identical'
  69. if math.isnan(x) or math.isnan(y):
  70. if math.isnan(x) and math.isnan(y):
  71. return
  72. elif x == y:
  73. if x != 0.0:
  74. return
  75. # both zero; check that signs match
  76. elif math.copysign(1.0, x) == math.copysign(1.0, y):
  77. return
  78. else:
  79. msg += ': zeros have different signs'
  80. self.fail(msg.format(x, y))
  81. def assertComplexIdentical(self, x, y):
  82. """Fail unless complex numbers x and y have equal values and signs.
  83. In particular, if x and y both have real (or imaginary) part
  84. zero, but the zeros have different signs, this test will fail.
  85. """
  86. self.assertFloatIdentical(x.real, y.real)
  87. self.assertFloatIdentical(x.imag, y.imag)
  88. def rAssertAlmostEqual(self, a, b, rel_err = 2e-15, abs_err = 5e-323,
  89. msg=None):
  90. """Fail if the two floating-point numbers are not almost equal.
  91. Determine whether floating-point values a and b are equal to within
  92. a (small) rounding error. The default values for rel_err and
  93. abs_err are chosen to be suitable for platforms where a float is
  94. represented by an IEEE 754 double. They allow an error of between
  95. 9 and 19 ulps.
  96. """
  97. # special values testing
  98. if math.isnan(a):
  99. if math.isnan(b):
  100. return
  101. self.fail(msg or '{!r} should be nan'.format(b))
  102. if math.isinf(a):
  103. if a == b:
  104. return
  105. self.fail(msg or 'finite result where infinity expected: '
  106. 'expected {!r}, got {!r}'.format(a, b))
  107. # if both a and b are zero, check whether they have the same sign
  108. # (in theory there are examples where it would be legitimate for a
  109. # and b to have opposite signs; in practice these hardly ever
  110. # occur).
  111. if not a and not b:
  112. if math.copysign(1., a) != math.copysign(1., b):
  113. self.fail(msg or 'zero has wrong sign: expected {!r}, '
  114. 'got {!r}'.format(a, b))
  115. # if a-b overflows, or b is infinite, return False. Again, in
  116. # theory there are examples where a is within a few ulps of the
  117. # max representable float, and then b could legitimately be
  118. # infinite. In practice these examples are rare.
  119. try:
  120. absolute_error = abs(b-a)
  121. except OverflowError:
  122. pass
  123. else:
  124. # test passes if either the absolute error or the relative
  125. # error is sufficiently small. The defaults amount to an
  126. # error of between 9 ulps and 19 ulps on an IEEE-754 compliant
  127. # machine.
  128. if absolute_error <= max(abs_err, rel_err * abs(a)):
  129. return
  130. self.fail(msg or
  131. '{!r} and {!r} are not sufficiently close'.format(a, b))
  132. def test_constants(self):
  133. e_expected = 2.71828182845904523536
  134. pi_expected = 3.14159265358979323846
  135. self.assertAlmostEqual(cmath.pi, pi_expected, places=9,
  136. msg="cmath.pi is {}; should be {}".format(cmath.pi, pi_expected))
  137. self.assertAlmostEqual(cmath.e, e_expected, places=9,
  138. msg="cmath.e is {}; should be {}".format(cmath.e, e_expected))
  139. def test_infinity_and_nan_constants(self):
  140. self.assertEqual(cmath.inf.real, math.inf)
  141. self.assertEqual(cmath.inf.imag, 0.0)
  142. self.assertEqual(cmath.infj.real, 0.0)
  143. self.assertEqual(cmath.infj.imag, math.inf)
  144. self.assertTrue(math.isnan(cmath.nan.real))
  145. self.assertEqual(cmath.nan.imag, 0.0)
  146. self.assertEqual(cmath.nanj.real, 0.0)
  147. self.assertTrue(math.isnan(cmath.nanj.imag))
  148. # Check consistency with reprs.
  149. self.assertEqual(repr(cmath.inf), "inf")
  150. self.assertEqual(repr(cmath.infj), "infj")
  151. self.assertEqual(repr(cmath.nan), "nan")
  152. self.assertEqual(repr(cmath.nanj), "nanj")
  153. def test_user_object(self):
  154. # Test automatic calling of __complex__ and __float__ by cmath
  155. # functions
  156. # some random values to use as test values; we avoid values
  157. # for which any of the functions in cmath is undefined
  158. # (i.e. 0., 1., -1., 1j, -1j) or would cause overflow
  159. cx_arg = 4.419414439 + 1.497100113j
  160. flt_arg = -6.131677725
  161. # a variety of non-complex numbers, used to check that
  162. # non-complex return values from __complex__ give an error
  163. non_complexes = ["not complex", 1, 5, 2., None,
  164. object(), NotImplemented]
  165. # Now we introduce a variety of classes whose instances might
  166. # end up being passed to the cmath functions
  167. # usual case: new-style class implementing __complex__
  168. class MyComplex(object):
  169. def __init__(self, value):
  170. self.value = value
  171. def __complex__(self):
  172. return self.value
  173. # old-style class implementing __complex__
  174. class MyComplexOS:
  175. def __init__(self, value):
  176. self.value = value
  177. def __complex__(self):
  178. return self.value
  179. # classes for which __complex__ raises an exception
  180. class SomeException(Exception):
  181. pass
  182. class MyComplexException(object):
  183. def __complex__(self):
  184. raise SomeException
  185. class MyComplexExceptionOS:
  186. def __complex__(self):
  187. raise SomeException
  188. # some classes not providing __float__ or __complex__
  189. class NeitherComplexNorFloat(object):
  190. pass
  191. class NeitherComplexNorFloatOS:
  192. pass
  193. class Index:
  194. def __int__(self): return 2
  195. def __index__(self): return 2
  196. class MyInt:
  197. def __int__(self): return 2
  198. # other possible combinations of __float__ and __complex__
  199. # that should work
  200. class FloatAndComplex(object):
  201. def __float__(self):
  202. return flt_arg
  203. def __complex__(self):
  204. return cx_arg
  205. class FloatAndComplexOS:
  206. def __float__(self):
  207. return flt_arg
  208. def __complex__(self):
  209. return cx_arg
  210. class JustFloat(object):
  211. def __float__(self):
  212. return flt_arg
  213. class JustFloatOS:
  214. def __float__(self):
  215. return flt_arg
  216. for f in self.test_functions:
  217. # usual usage
  218. self.assertEqual(f(MyComplex(cx_arg)), f(cx_arg))
  219. self.assertEqual(f(MyComplexOS(cx_arg)), f(cx_arg))
  220. # other combinations of __float__ and __complex__
  221. self.assertEqual(f(FloatAndComplex()), f(cx_arg))
  222. self.assertEqual(f(FloatAndComplexOS()), f(cx_arg))
  223. self.assertEqual(f(JustFloat()), f(flt_arg))
  224. self.assertEqual(f(JustFloatOS()), f(flt_arg))
  225. self.assertEqual(f(Index()), f(int(Index())))
  226. # TypeError should be raised for classes not providing
  227. # either __complex__ or __float__, even if they provide
  228. # __int__ or __index__. An old-style class
  229. # currently raises AttributeError instead of a TypeError;
  230. # this could be considered a bug.
  231. self.assertRaises(TypeError, f, NeitherComplexNorFloat())
  232. self.assertRaises(TypeError, f, MyInt())
  233. self.assertRaises(Exception, f, NeitherComplexNorFloatOS())
  234. # non-complex return value from __complex__ -> TypeError
  235. for bad_complex in non_complexes:
  236. self.assertRaises(TypeError, f, MyComplex(bad_complex))
  237. self.assertRaises(TypeError, f, MyComplexOS(bad_complex))
  238. # exceptions in __complex__ should be propagated correctly
  239. self.assertRaises(SomeException, f, MyComplexException())
  240. self.assertRaises(SomeException, f, MyComplexExceptionOS())
  241. def test_input_type(self):
  242. # ints should be acceptable inputs to all cmath
  243. # functions, by virtue of providing a __float__ method
  244. for f in self.test_functions:
  245. for arg in [2, 2.]:
  246. self.assertEqual(f(arg), f(arg.__float__()))
  247. # but strings should give a TypeError
  248. for f in self.test_functions:
  249. for arg in ["a", "long_string", "0", "1j", ""]:
  250. self.assertRaises(TypeError, f, arg)
  251. def test_cmath_matches_math(self):
  252. # check that corresponding cmath and math functions are equal
  253. # for floats in the appropriate range
  254. # test_values in (0, 1)
  255. test_values = [0.01, 0.1, 0.2, 0.5, 0.9, 0.99]
  256. # test_values for functions defined on [-1., 1.]
  257. unit_interval = test_values + [-x for x in test_values] + \
  258. [0., 1., -1.]
  259. # test_values for log, log10, sqrt
  260. positive = test_values + [1.] + [1./x for x in test_values]
  261. nonnegative = [0.] + positive
  262. # test_values for functions defined on the whole real line
  263. real_line = [0.] + positive + [-x for x in positive]
  264. test_functions = {
  265. 'acos' : unit_interval,
  266. 'asin' : unit_interval,
  267. 'atan' : real_line,
  268. 'cos' : real_line,
  269. 'cosh' : real_line,
  270. 'exp' : real_line,
  271. 'log' : positive,
  272. 'log10' : positive,
  273. 'sin' : real_line,
  274. 'sinh' : real_line,
  275. 'sqrt' : nonnegative,
  276. 'tan' : real_line,
  277. 'tanh' : real_line}
  278. for fn, values in test_functions.items():
  279. float_fn = getattr(math, fn)
  280. complex_fn = getattr(cmath, fn)
  281. for v in values:
  282. z = complex_fn(v)
  283. self.rAssertAlmostEqual(float_fn(v), z.real)
  284. self.assertEqual(0., z.imag)
  285. # test two-argument version of log with various bases
  286. for base in [0.5, 2., 10.]:
  287. for v in positive:
  288. z = cmath.log(v, base)
  289. self.rAssertAlmostEqual(math.log(v, base), z.real)
  290. self.assertEqual(0., z.imag)
  291. @requires_IEEE_754
  292. def test_specific_values(self):
  293. # Some tests need to be skipped on ancient OS X versions.
  294. # See issue #27953.
  295. SKIP_ON_TIGER = {'tan0064'}
  296. osx_version = None
  297. if sys.platform == 'darwin':
  298. version_txt = platform.mac_ver()[0]
  299. try:
  300. osx_version = tuple(map(int, version_txt.split('.')))
  301. except ValueError:
  302. pass
  303. def rect_complex(z):
  304. """Wrapped version of rect that accepts a complex number instead of
  305. two float arguments."""
  306. return cmath.rect(z.real, z.imag)
  307. def polar_complex(z):
  308. """Wrapped version of polar that returns a complex number instead of
  309. two floats."""
  310. return complex(*polar(z))
  311. for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file):
  312. arg = complex(ar, ai)
  313. expected = complex(er, ei)
  314. # Skip certain tests on OS X 10.4.
  315. if osx_version is not None and osx_version < (10, 5):
  316. if id in SKIP_ON_TIGER:
  317. continue
  318. if fn == 'rect':
  319. function = rect_complex
  320. elif fn == 'polar':
  321. function = polar_complex
  322. else:
  323. function = getattr(cmath, fn)
  324. if 'divide-by-zero' in flags or 'invalid' in flags:
  325. try:
  326. actual = function(arg)
  327. except ValueError:
  328. continue
  329. else:
  330. self.fail('ValueError not raised in test '
  331. '{}: {}(complex({!r}, {!r}))'.format(id, fn, ar, ai))
  332. if 'overflow' in flags:
  333. try:
  334. actual = function(arg)
  335. except OverflowError:
  336. continue
  337. else:
  338. self.fail('OverflowError not raised in test '
  339. '{}: {}(complex({!r}, {!r}))'.format(id, fn, ar, ai))
  340. actual = function(arg)
  341. if 'ignore-real-sign' in flags:
  342. actual = complex(abs(actual.real), actual.imag)
  343. expected = complex(abs(expected.real), expected.imag)
  344. if 'ignore-imag-sign' in flags:
  345. actual = complex(actual.real, abs(actual.imag))
  346. expected = complex(expected.real, abs(expected.imag))
  347. # for the real part of the log function, we allow an
  348. # absolute error of up to 2e-15.
  349. if fn in ('log', 'log10'):
  350. real_abs_err = 2e-15
  351. else:
  352. real_abs_err = 5e-323
  353. error_message = (
  354. '{}: {}(complex({!r}, {!r}))\n'
  355. 'Expected: complex({!r}, {!r})\n'
  356. 'Received: complex({!r}, {!r})\n'
  357. 'Received value insufficiently close to expected value.'
  358. ).format(id, fn, ar, ai,
  359. expected.real, expected.imag,
  360. actual.real, actual.imag)
  361. self.rAssertAlmostEqual(expected.real, actual.real,
  362. abs_err=real_abs_err,
  363. msg=error_message)
  364. self.rAssertAlmostEqual(expected.imag, actual.imag,
  365. msg=error_message)
  366. def check_polar(self, func):
  367. def check(arg, expected):
  368. got = func(arg)
  369. for e, g in zip(expected, got):
  370. self.rAssertAlmostEqual(e, g)
  371. check(0, (0., 0.))
  372. check(1, (1., 0.))
  373. check(-1, (1., pi))
  374. check(1j, (1., pi / 2))
  375. check(-3j, (3., -pi / 2))
  376. inf = float('inf')
  377. check(complex(inf, 0), (inf, 0.))
  378. check(complex(-inf, 0), (inf, pi))
  379. check(complex(3, inf), (inf, pi / 2))
  380. check(complex(5, -inf), (inf, -pi / 2))
  381. check(complex(inf, inf), (inf, pi / 4))
  382. check(complex(inf, -inf), (inf, -pi / 4))
  383. check(complex(-inf, inf), (inf, 3 * pi / 4))
  384. check(complex(-inf, -inf), (inf, -3 * pi / 4))
  385. nan = float('nan')
  386. check(complex(nan, 0), (nan, nan))
  387. check(complex(0, nan), (nan, nan))
  388. check(complex(nan, nan), (nan, nan))
  389. check(complex(inf, nan), (inf, nan))
  390. check(complex(-inf, nan), (inf, nan))
  391. check(complex(nan, inf), (inf, nan))
  392. check(complex(nan, -inf), (inf, nan))
  393. def test_polar(self):
  394. self.check_polar(polar)
  395. @cpython_only
  396. def test_polar_errno(self):
  397. # Issue #24489: check a previously set C errno doesn't disturb polar()
  398. _testcapi = import_helper.import_module('_testcapi')
  399. def polar_with_errno_set(z):
  400. _testcapi.set_errno(11)
  401. try:
  402. return polar(z)
  403. finally:
  404. _testcapi.set_errno(0)
  405. self.check_polar(polar_with_errno_set)
  406. def test_phase(self):
  407. self.assertAlmostEqual(phase(0), 0.)
  408. self.assertAlmostEqual(phase(1.), 0.)
  409. self.assertAlmostEqual(phase(-1.), pi)
  410. self.assertAlmostEqual(phase(-1.+1E-300j), pi)
  411. self.assertAlmostEqual(phase(-1.-1E-300j), -pi)
  412. self.assertAlmostEqual(phase(1j), pi/2)
  413. self.assertAlmostEqual(phase(-1j), -pi/2)
  414. # zeros
  415. self.assertEqual(phase(complex(0.0, 0.0)), 0.0)
  416. self.assertEqual(phase(complex(0.0, -0.0)), -0.0)
  417. self.assertEqual(phase(complex(-0.0, 0.0)), pi)
  418. self.assertEqual(phase(complex(-0.0, -0.0)), -pi)
  419. # infinities
  420. self.assertAlmostEqual(phase(complex(-INF, -0.0)), -pi)
  421. self.assertAlmostEqual(phase(complex(-INF, -2.3)), -pi)
  422. self.assertAlmostEqual(phase(complex(-INF, -INF)), -0.75*pi)
  423. self.assertAlmostEqual(phase(complex(-2.3, -INF)), -pi/2)
  424. self.assertAlmostEqual(phase(complex(-0.0, -INF)), -pi/2)
  425. self.assertAlmostEqual(phase(complex(0.0, -INF)), -pi/2)
  426. self.assertAlmostEqual(phase(complex(2.3, -INF)), -pi/2)
  427. self.assertAlmostEqual(phase(complex(INF, -INF)), -pi/4)
  428. self.assertEqual(phase(complex(INF, -2.3)), -0.0)
  429. self.assertEqual(phase(complex(INF, -0.0)), -0.0)
  430. self.assertEqual(phase(complex(INF, 0.0)), 0.0)
  431. self.assertEqual(phase(complex(INF, 2.3)), 0.0)
  432. self.assertAlmostEqual(phase(complex(INF, INF)), pi/4)
  433. self.assertAlmostEqual(phase(complex(2.3, INF)), pi/2)
  434. self.assertAlmostEqual(phase(complex(0.0, INF)), pi/2)
  435. self.assertAlmostEqual(phase(complex(-0.0, INF)), pi/2)
  436. self.assertAlmostEqual(phase(complex(-2.3, INF)), pi/2)
  437. self.assertAlmostEqual(phase(complex(-INF, INF)), 0.75*pi)
  438. self.assertAlmostEqual(phase(complex(-INF, 2.3)), pi)
  439. self.assertAlmostEqual(phase(complex(-INF, 0.0)), pi)
  440. # real or imaginary part NaN
  441. for z in complex_nans:
  442. self.assertTrue(math.isnan(phase(z)))
  443. def test_abs(self):
  444. # zeros
  445. for z in complex_zeros:
  446. self.assertEqual(abs(z), 0.0)
  447. # infinities
  448. for z in complex_infinities:
  449. self.assertEqual(abs(z), INF)
  450. # real or imaginary part NaN
  451. self.assertEqual(abs(complex(NAN, -INF)), INF)
  452. self.assertTrue(math.isnan(abs(complex(NAN, -2.3))))
  453. self.assertTrue(math.isnan(abs(complex(NAN, -0.0))))
  454. self.assertTrue(math.isnan(abs(complex(NAN, 0.0))))
  455. self.assertTrue(math.isnan(abs(complex(NAN, 2.3))))
  456. self.assertEqual(abs(complex(NAN, INF)), INF)
  457. self.assertEqual(abs(complex(-INF, NAN)), INF)
  458. self.assertTrue(math.isnan(abs(complex(-2.3, NAN))))
  459. self.assertTrue(math.isnan(abs(complex(-0.0, NAN))))
  460. self.assertTrue(math.isnan(abs(complex(0.0, NAN))))
  461. self.assertTrue(math.isnan(abs(complex(2.3, NAN))))
  462. self.assertEqual(abs(complex(INF, NAN)), INF)
  463. self.assertTrue(math.isnan(abs(complex(NAN, NAN))))
  464. @requires_IEEE_754
  465. def test_abs_overflows(self):
  466. # result overflows
  467. self.assertRaises(OverflowError, abs, complex(1.4e308, 1.4e308))
  468. def assertCEqual(self, a, b):
  469. eps = 1E-7
  470. if abs(a.real - b[0]) > eps or abs(a.imag - b[1]) > eps:
  471. self.fail((a ,b))
  472. def test_rect(self):
  473. self.assertCEqual(rect(0, 0), (0, 0))
  474. self.assertCEqual(rect(1, 0), (1., 0))
  475. self.assertCEqual(rect(1, -pi), (-1., 0))
  476. self.assertCEqual(rect(1, pi/2), (0, 1.))
  477. self.assertCEqual(rect(1, -pi/2), (0, -1.))
  478. def test_isfinite(self):
  479. real_vals = [float('-inf'), -2.3, -0.0,
  480. 0.0, 2.3, float('inf'), float('nan')]
  481. for x in real_vals:
  482. for y in real_vals:
  483. z = complex(x, y)
  484. self.assertEqual(cmath.isfinite(z),
  485. math.isfinite(x) and math.isfinite(y))
  486. def test_isnan(self):
  487. self.assertFalse(cmath.isnan(1))
  488. self.assertFalse(cmath.isnan(1j))
  489. self.assertFalse(cmath.isnan(INF))
  490. self.assertTrue(cmath.isnan(NAN))
  491. self.assertTrue(cmath.isnan(complex(NAN, 0)))
  492. self.assertTrue(cmath.isnan(complex(0, NAN)))
  493. self.assertTrue(cmath.isnan(complex(NAN, NAN)))
  494. self.assertTrue(cmath.isnan(complex(NAN, INF)))
  495. self.assertTrue(cmath.isnan(complex(INF, NAN)))
  496. def test_isinf(self):
  497. self.assertFalse(cmath.isinf(1))
  498. self.assertFalse(cmath.isinf(1j))
  499. self.assertFalse(cmath.isinf(NAN))
  500. self.assertTrue(cmath.isinf(INF))
  501. self.assertTrue(cmath.isinf(complex(INF, 0)))
  502. self.assertTrue(cmath.isinf(complex(0, INF)))
  503. self.assertTrue(cmath.isinf(complex(INF, INF)))
  504. self.assertTrue(cmath.isinf(complex(NAN, INF)))
  505. self.assertTrue(cmath.isinf(complex(INF, NAN)))
  506. @requires_IEEE_754
  507. def testTanhSign(self):
  508. for z in complex_zeros:
  509. self.assertComplexIdentical(cmath.tanh(z), z)
  510. # The algorithm used for atan and atanh makes use of the system
  511. # log1p function; If that system function doesn't respect the sign
  512. # of zero, then atan and atanh will also have difficulties with
  513. # the sign of complex zeros.
  514. @requires_IEEE_754
  515. def testAtanSign(self):
  516. for z in complex_zeros:
  517. self.assertComplexIdentical(cmath.atan(z), z)
  518. @requires_IEEE_754
  519. def testAtanhSign(self):
  520. for z in complex_zeros:
  521. self.assertComplexIdentical(cmath.atanh(z), z)
  522. class IsCloseTests(test_math.IsCloseTests):
  523. isclose = cmath.isclose
  524. def test_reject_complex_tolerances(self):
  525. with self.assertRaises(TypeError):
  526. self.isclose(1j, 1j, rel_tol=1j)
  527. with self.assertRaises(TypeError):
  528. self.isclose(1j, 1j, abs_tol=1j)
  529. with self.assertRaises(TypeError):
  530. self.isclose(1j, 1j, rel_tol=1j, abs_tol=1j)
  531. def test_complex_values(self):
  532. # test complex values that are close to within 12 decimal places
  533. complex_examples = [(1.0+1.0j, 1.000000000001+1.0j),
  534. (1.0+1.0j, 1.0+1.000000000001j),
  535. (-1.0+1.0j, -1.000000000001+1.0j),
  536. (1.0-1.0j, 1.0-0.999999999999j),
  537. ]
  538. self.assertAllClose(complex_examples, rel_tol=1e-12)
  539. self.assertAllNotClose(complex_examples, rel_tol=1e-13)
  540. def test_complex_near_zero(self):
  541. # test values near zero that are near to within three decimal places
  542. near_zero_examples = [(0.001j, 0),
  543. (0.001, 0),
  544. (0.001+0.001j, 0),
  545. (-0.001+0.001j, 0),
  546. (0.001-0.001j, 0),
  547. (-0.001-0.001j, 0),
  548. ]
  549. self.assertAllClose(near_zero_examples, abs_tol=1.5e-03)
  550. self.assertAllNotClose(near_zero_examples, abs_tol=0.5e-03)
  551. self.assertIsClose(0.001-0.001j, 0.001+0.001j, abs_tol=2e-03)
  552. self.assertIsNotClose(0.001-0.001j, 0.001+0.001j, abs_tol=1e-03)
  553. if __name__ == "__main__":
  554. unittest.main()