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