• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
9
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, 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 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 Index:
224            def __int__(self): return 2
225            def __index__(self): return 2
226        class MyInt:
227            def __int__(self): return 2
228
229        # other possible combinations of __float__ and __complex__
230        # that should work
231        class FloatAndComplex(object):
232            def __float__(self):
233                return flt_arg
234            def __complex__(self):
235                return cx_arg
236        class FloatAndComplexOS:
237            def __float__(self):
238                return flt_arg
239            def __complex__(self):
240                return cx_arg
241        class JustFloat(object):
242            def __float__(self):
243                return flt_arg
244        class JustFloatOS:
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        from _testcapi import set_errno
456        def polar_with_errno_set(z):
457            set_errno(11)
458            try:
459                return polar(z)
460            finally:
461                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
598class IsCloseTests(test_math.IsCloseTests):
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
639if __name__ == "__main__":
640    unittest.main()
641