1from test.support import requires_IEEE_754, cpython_only
2from test.test_math import parse_testfile, test_file
3import test.test_math as test_math
4import unittest
5import cmath, math
6from cmath import phase, polar, rect, pi
7import platform
8import sys
9import sysconfig
10
11INF = float('inf')
12NAN = float('nan')
13
14complex_zeros = [complex(x, y) for x in [0.0, -0.0] for y in [0.0, -0.0]]
15complex_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        ]]
37complex_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
52class CMathTests(unittest.TestCase):
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)
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 MyComplex(object):
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 MyComplexOS:
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 SomeException(Exception):
210            pass
211        class MyComplexException(object):
212            def __complex__(self):
213                raise SomeException
214        class MyComplexExceptionOS:
215            def __complex__(self):
216                raise SomeException
217
218        # some classes not providing __float__ or __complex__
219        class NeitherComplexNorFloat(object):
220            pass
221        class NeitherComplexNorFloatOS:
222            pass
223        class MyInt(object):
224            def __int__(self): return 2
225            def __index__(self): return 2
226        class MyIntOS:
227            def __int__(self): return 2
228            def __index__(self): return 2
229
230        # other possible combinations of __float__ and __complex__
231        # that should work
232        class FloatAndComplex(object):
233            def __float__(self):
234                return flt_arg
235            def __complex__(self):
236                return cx_arg
237        class FloatAndComplexOS:
238            def __float__(self):
239                return flt_arg
240            def __complex__(self):
241                return cx_arg
242        class JustFloat(object):
243            def __float__(self):
244                return flt_arg
245        class JustFloatOS:
246            def __float__(self):
247                return flt_arg
248
249        for f in self.test_functions:
250            # usual usage
251            self.assertEqual(f(MyComplex(cx_arg)), f(cx_arg))
252            self.assertEqual(f(MyComplexOS(cx_arg)), f(cx_arg))
253            # other combinations of __float__ and __complex__
254            self.assertEqual(f(FloatAndComplex()), f(cx_arg))
255            self.assertEqual(f(FloatAndComplexOS()), f(cx_arg))
256            self.assertEqual(f(JustFloat()), f(flt_arg))
257            self.assertEqual(f(JustFloatOS()), f(flt_arg))
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            self.assertRaises(Exception, f, MyIntOS())
267            # non-complex return value from __complex__ -> TypeError
268            for bad_complex in non_complexes:
269                self.assertRaises(TypeError, f, MyComplex(bad_complex))
270                self.assertRaises(TypeError, f, MyComplexOS(bad_complex))
271            # exceptions in __complex__ should be propagated correctly
272            self.assertRaises(SomeException, f, MyComplexException())
273            self.assertRaises(SomeException, f, MyComplexExceptionOS())
274
275    def test_input_type(self):
276        # ints should be acceptable inputs to all cmath
277        # functions, by virtue of providing a __float__ method
278        for f in self.test_functions:
279            for arg in [2, 2.]:
280                self.assertEqual(f(arg), f(arg.__float__()))
281
282        # but strings should give a TypeError
283        for f in self.test_functions:
284            for arg in ["a", "long_string", "0", "1j", ""]:
285                self.assertRaises(TypeError, f, arg)
286
287    def test_cmath_matches_math(self):
288        # check that corresponding cmath and math functions are equal
289        # for floats in the appropriate range
290
291        # test_values in (0, 1)
292        test_values = [0.01, 0.1, 0.2, 0.5, 0.9, 0.99]
293
294        # test_values for functions defined on [-1., 1.]
295        unit_interval = test_values + [-x for x in test_values] + \
296            [0., 1., -1.]
297
298        # test_values for log, log10, sqrt
299        positive = test_values + [1.] + [1./x for x in test_values]
300        nonnegative = [0.] + positive
301
302        # test_values for functions defined on the whole real line
303        real_line = [0.] + positive + [-x for x in positive]
304
305        test_functions = {
306            'acos' : unit_interval,
307            'asin' : unit_interval,
308            'atan' : real_line,
309            'cos' : real_line,
310            'cosh' : real_line,
311            'exp' : real_line,
312            'log' : positive,
313            'log10' : positive,
314            'sin' : real_line,
315            'sinh' : real_line,
316            'sqrt' : nonnegative,
317            'tan' : real_line,
318            'tanh' : real_line}
319
320        for fn, values in test_functions.items():
321            float_fn = getattr(math, fn)
322            complex_fn = getattr(cmath, fn)
323            for v in values:
324                z = complex_fn(v)
325                self.rAssertAlmostEqual(float_fn(v), z.real)
326                self.assertEqual(0., z.imag)
327
328        # test two-argument version of log with various bases
329        for base in [0.5, 2., 10.]:
330            for v in positive:
331                z = cmath.log(v, base)
332                self.rAssertAlmostEqual(math.log(v, base), z.real)
333                self.assertEqual(0., z.imag)
334
335    @requires_IEEE_754
336    def test_specific_values(self):
337        # Some tests need to be skipped on ancient OS X versions.
338        # See issue #27953.
339        SKIP_ON_TIGER = {'tan0064'}
340
341        osx_version = None
342        if sys.platform == 'darwin':
343            version_txt = platform.mac_ver()[0]
344            try:
345                osx_version = tuple(map(int, version_txt.split('.')))
346            except ValueError:
347                pass
348
349        def rect_complex(z):
350            """Wrapped version of rect that accepts a complex number instead of
351            two float arguments."""
352            return cmath.rect(z.real, z.imag)
353
354        def polar_complex(z):
355            """Wrapped version of polar that returns a complex number instead of
356            two floats."""
357            return complex(*polar(z))
358
359        for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file):
360            arg = complex(ar, ai)
361            expected = complex(er, ei)
362
363            # Skip certain tests on OS X 10.4.
364            if osx_version is not None and osx_version < (10, 5):
365                if id in SKIP_ON_TIGER:
366                    continue
367
368            if fn == 'rect':
369                function = rect_complex
370            elif fn == 'polar':
371                function = polar_complex
372            else:
373                function = getattr(cmath, fn)
374            if 'divide-by-zero' in flags or 'invalid' in flags:
375                try:
376                    actual = function(arg)
377                except ValueError:
378                    continue
379                else:
380                    self.fail('ValueError not raised in test '
381                          '{}: {}(complex({!r}, {!r}))'.format(id, fn, ar, ai))
382
383            if 'overflow' in flags:
384                try:
385                    actual = function(arg)
386                except OverflowError:
387                    continue
388                else:
389                    self.fail('OverflowError not raised in test '
390                          '{}: {}(complex({!r}, {!r}))'.format(id, fn, ar, ai))
391
392            actual = function(arg)
393
394            if 'ignore-real-sign' in flags:
395                actual = complex(abs(actual.real), actual.imag)
396                expected = complex(abs(expected.real), expected.imag)
397            if 'ignore-imag-sign' in flags:
398                actual = complex(actual.real, abs(actual.imag))
399                expected = complex(expected.real, abs(expected.imag))
400
401            # for the real part of the log function, we allow an
402            # absolute error of up to 2e-15.
403            if fn in ('log', 'log10'):
404                real_abs_err = 2e-15
405            else:
406                real_abs_err = 5e-323
407
408            error_message = (
409                '{}: {}(complex({!r}, {!r}))\n'
410                'Expected: complex({!r}, {!r})\n'
411                'Received: complex({!r}, {!r})\n'
412                'Received value insufficiently close to expected value.'
413                ).format(id, fn, ar, ai,
414                     expected.real, expected.imag,
415                     actual.real, actual.imag)
416            self.rAssertAlmostEqual(expected.real, actual.real,
417                                        abs_err=real_abs_err,
418                                        msg=error_message)
419            self.rAssertAlmostEqual(expected.imag, actual.imag,
420                                        msg=error_message)
421
422    def check_polar(self, func):
423        def check(arg, expected):
424            got = func(arg)
425            for e, g in zip(expected, got):
426                self.rAssertAlmostEqual(e, g)
427        check(0, (0., 0.))
428        check(1, (1., 0.))
429        check(-1, (1., pi))
430        check(1j, (1., pi / 2))
431        check(-3j, (3., -pi / 2))
432        inf = float('inf')
433        check(complex(inf, 0), (inf, 0.))
434        check(complex(-inf, 0), (inf, pi))
435        check(complex(3, inf), (inf, pi / 2))
436        check(complex(5, -inf), (inf, -pi / 2))
437        check(complex(inf, inf), (inf, pi / 4))
438        check(complex(inf, -inf), (inf, -pi / 4))
439        check(complex(-inf, inf), (inf, 3 * pi / 4))
440        check(complex(-inf, -inf), (inf, -3 * pi / 4))
441        nan = float('nan')
442        check(complex(nan, 0), (nan, nan))
443        check(complex(0, nan), (nan, nan))
444        check(complex(nan, nan), (nan, nan))
445        check(complex(inf, nan), (inf, nan))
446        check(complex(-inf, nan), (inf, nan))
447        check(complex(nan, inf), (inf, nan))
448        check(complex(nan, -inf), (inf, nan))
449
450    def test_polar(self):
451        self.check_polar(polar)
452
453    @cpython_only
454    def test_polar_errno(self):
455        # Issue #24489: check a previously set C errno doesn't disturb polar()
456        from _testcapi import set_errno
457        def polar_with_errno_set(z):
458            set_errno(11)
459            try:
460                return polar(z)
461            finally:
462                set_errno(0)
463        self.check_polar(polar_with_errno_set)
464
465    def test_phase(self):
466        self.assertAlmostEqual(phase(0), 0.)
467        self.assertAlmostEqual(phase(1.), 0.)
468        self.assertAlmostEqual(phase(-1.), pi)
469        self.assertAlmostEqual(phase(-1.+1E-300j), pi)
470        self.assertAlmostEqual(phase(-1.-1E-300j), -pi)
471        self.assertAlmostEqual(phase(1j), pi/2)
472        self.assertAlmostEqual(phase(-1j), -pi/2)
473
474        # zeros
475        self.assertEqual(phase(complex(0.0, 0.0)), 0.0)
476        self.assertEqual(phase(complex(0.0, -0.0)), -0.0)
477        self.assertEqual(phase(complex(-0.0, 0.0)), pi)
478        self.assertEqual(phase(complex(-0.0, -0.0)), -pi)
479
480        # infinities
481        self.assertAlmostEqual(phase(complex(-INF, -0.0)), -pi)
482        self.assertAlmostEqual(phase(complex(-INF, -2.3)), -pi)
483        self.assertAlmostEqual(phase(complex(-INF, -INF)), -0.75*pi)
484        self.assertAlmostEqual(phase(complex(-2.3, -INF)), -pi/2)
485        self.assertAlmostEqual(phase(complex(-0.0, -INF)), -pi/2)
486        self.assertAlmostEqual(phase(complex(0.0, -INF)), -pi/2)
487        self.assertAlmostEqual(phase(complex(2.3, -INF)), -pi/2)
488        self.assertAlmostEqual(phase(complex(INF, -INF)), -pi/4)
489        self.assertEqual(phase(complex(INF, -2.3)), -0.0)
490        self.assertEqual(phase(complex(INF, -0.0)), -0.0)
491        self.assertEqual(phase(complex(INF, 0.0)), 0.0)
492        self.assertEqual(phase(complex(INF, 2.3)), 0.0)
493        self.assertAlmostEqual(phase(complex(INF, INF)), pi/4)
494        self.assertAlmostEqual(phase(complex(2.3, INF)), pi/2)
495        self.assertAlmostEqual(phase(complex(0.0, INF)), pi/2)
496        self.assertAlmostEqual(phase(complex(-0.0, INF)), pi/2)
497        self.assertAlmostEqual(phase(complex(-2.3, INF)), pi/2)
498        self.assertAlmostEqual(phase(complex(-INF, INF)), 0.75*pi)
499        self.assertAlmostEqual(phase(complex(-INF, 2.3)), pi)
500        self.assertAlmostEqual(phase(complex(-INF, 0.0)), pi)
501
502        # real or imaginary part NaN
503        for z in complex_nans:
504            self.assertTrue(math.isnan(phase(z)))
505
506    def test_abs(self):
507        # zeros
508        for z in complex_zeros:
509            self.assertEqual(abs(z), 0.0)
510
511        # infinities
512        for z in complex_infinities:
513            self.assertEqual(abs(z), INF)
514
515        # real or imaginary part NaN
516        self.assertEqual(abs(complex(NAN, -INF)), INF)
517        self.assertTrue(math.isnan(abs(complex(NAN, -2.3))))
518        self.assertTrue(math.isnan(abs(complex(NAN, -0.0))))
519        self.assertTrue(math.isnan(abs(complex(NAN, 0.0))))
520        self.assertTrue(math.isnan(abs(complex(NAN, 2.3))))
521        self.assertEqual(abs(complex(NAN, INF)), INF)
522        self.assertEqual(abs(complex(-INF, NAN)), INF)
523        self.assertTrue(math.isnan(abs(complex(-2.3, NAN))))
524        self.assertTrue(math.isnan(abs(complex(-0.0, NAN))))
525        self.assertTrue(math.isnan(abs(complex(0.0, NAN))))
526        self.assertTrue(math.isnan(abs(complex(2.3, NAN))))
527        self.assertEqual(abs(complex(INF, NAN)), INF)
528        self.assertTrue(math.isnan(abs(complex(NAN, NAN))))
529
530
531    @requires_IEEE_754
532    def test_abs_overflows(self):
533        # result overflows
534        self.assertRaises(OverflowError, abs, complex(1.4e308, 1.4e308))
535
536    def assertCEqual(self, a, b):
537        eps = 1E-7
538        if abs(a.real - b[0]) > eps or abs(a.imag - b[1]) > eps:
539            self.fail((a ,b))
540
541    def test_rect(self):
542        self.assertCEqual(rect(0, 0), (0, 0))
543        self.assertCEqual(rect(1, 0), (1., 0))
544        self.assertCEqual(rect(1, -pi), (-1., 0))
545        self.assertCEqual(rect(1, pi/2), (0, 1.))
546        self.assertCEqual(rect(1, -pi/2), (0, -1.))
547
548    def test_isfinite(self):
549        real_vals = [float('-inf'), -2.3, -0.0,
550                     0.0, 2.3, float('inf'), float('nan')]
551        for x in real_vals:
552            for y in real_vals:
553                z = complex(x, y)
554                self.assertEqual(cmath.isfinite(z),
555                                  math.isfinite(x) and math.isfinite(y))
556
557    def test_isnan(self):
558        self.assertFalse(cmath.isnan(1))
559        self.assertFalse(cmath.isnan(1j))
560        self.assertFalse(cmath.isnan(INF))
561        self.assertTrue(cmath.isnan(NAN))
562        self.assertTrue(cmath.isnan(complex(NAN, 0)))
563        self.assertTrue(cmath.isnan(complex(0, NAN)))
564        self.assertTrue(cmath.isnan(complex(NAN, NAN)))
565        self.assertTrue(cmath.isnan(complex(NAN, INF)))
566        self.assertTrue(cmath.isnan(complex(INF, NAN)))
567
568    def test_isinf(self):
569        self.assertFalse(cmath.isinf(1))
570        self.assertFalse(cmath.isinf(1j))
571        self.assertFalse(cmath.isinf(NAN))
572        self.assertTrue(cmath.isinf(INF))
573        self.assertTrue(cmath.isinf(complex(INF, 0)))
574        self.assertTrue(cmath.isinf(complex(0, INF)))
575        self.assertTrue(cmath.isinf(complex(INF, INF)))
576        self.assertTrue(cmath.isinf(complex(NAN, INF)))
577        self.assertTrue(cmath.isinf(complex(INF, NAN)))
578
579    @requires_IEEE_754
580    @unittest.skipIf(sysconfig.get_config_var('TANH_PRESERVES_ZERO_SIGN') == 0,
581                     "system tanh() function doesn't copy the sign")
582    def testTanhSign(self):
583        for z in complex_zeros:
584            self.assertComplexIdentical(cmath.tanh(z), z)
585
586    # The algorithm used for atan and atanh makes use of the system
587    # log1p function; If that system function doesn't respect the sign
588    # of zero, then atan and atanh will also have difficulties with
589    # the sign of complex zeros.
590    @requires_IEEE_754
591    def testAtanSign(self):
592        for z in complex_zeros:
593            self.assertComplexIdentical(cmath.atan(z), z)
594
595    @requires_IEEE_754
596    def testAtanhSign(self):
597        for z in complex_zeros:
598            self.assertComplexIdentical(cmath.atanh(z), z)
599
600
601class IsCloseTests(test_math.IsCloseTests):
602    isclose = cmath.isclose
603
604    def test_reject_complex_tolerances(self):
605        with self.assertRaises(TypeError):
606            self.isclose(1j, 1j, rel_tol=1j)
607
608        with self.assertRaises(TypeError):
609            self.isclose(1j, 1j, abs_tol=1j)
610
611        with self.assertRaises(TypeError):
612            self.isclose(1j, 1j, rel_tol=1j, abs_tol=1j)
613
614    def test_complex_values(self):
615        # test complex values that are close to within 12 decimal places
616        complex_examples = [(1.0+1.0j, 1.000000000001+1.0j),
617                            (1.0+1.0j, 1.0+1.000000000001j),
618                            (-1.0+1.0j, -1.000000000001+1.0j),
619                            (1.0-1.0j, 1.0-0.999999999999j),
620                            ]
621
622        self.assertAllClose(complex_examples, rel_tol=1e-12)
623        self.assertAllNotClose(complex_examples, rel_tol=1e-13)
624
625    def test_complex_near_zero(self):
626        # test values near zero that are near to within three decimal places
627        near_zero_examples = [(0.001j, 0),
628                              (0.001, 0),
629                              (0.001+0.001j, 0),
630                              (-0.001+0.001j, 0),
631                              (0.001-0.001j, 0),
632                              (-0.001-0.001j, 0),
633                              ]
634
635        self.assertAllClose(near_zero_examples, abs_tol=1.5e-03)
636        self.assertAllNotClose(near_zero_examples, abs_tol=0.5e-03)
637
638        self.assertIsClose(0.001-0.001j, 0.001+0.001j, abs_tol=2e-03)
639        self.assertIsNotClose(0.001-0.001j, 0.001+0.001j, abs_tol=1e-03)
640
641
642if __name__ == "__main__":
643    unittest.main()
644