2
from test import test_support
5
warnings.filterwarnings(
7
category=DeprecationWarning,
8
message=".*complex divmod.*are deprecated"
11
from random import random
12
from math import atan2
16
# These tests ensure that complex math does the right thing
18
class ComplexTest(unittest.TestCase):
20
def assertAlmostEqual(self, a, b):
21
if isinstance(a, complex):
22
if isinstance(b, complex):
23
unittest.TestCase.assertAlmostEqual(self, a.real, b.real)
24
unittest.TestCase.assertAlmostEqual(self, a.imag, b.imag)
26
unittest.TestCase.assertAlmostEqual(self, a.real, b)
27
unittest.TestCase.assertAlmostEqual(self, a.imag, 0.)
29
if isinstance(b, complex):
30
unittest.TestCase.assertAlmostEqual(self, a, b.real)
31
unittest.TestCase.assertAlmostEqual(self, 0., b.imag)
33
unittest.TestCase.assertAlmostEqual(self, a, b)
35
def assertCloseAbs(self, x, y, eps=1e-9):
36
"""Return true iff floats x and y "are close\""""
37
# put the one with larger magnitude second
44
# check that relative difference < eps
45
self.assert_(abs((x-y)/y) < eps)
47
def assertClose(self, x, y, eps=1e-9):
48
"""Return true iff complexes x and y "are close\""""
49
self.assertCloseAbs(x.real, y.real, eps)
50
self.assertCloseAbs(x.imag, y.imag, eps)
52
def assertIs(self, a, b):
55
def check_div(self, x, y):
56
"""Compute complex z=x*y, and check that z/x==y and z/y==x."""
60
self.assertClose(q, y)
62
self.assertClose(q, y)
64
self.assertClose(q, y)
67
self.assertClose(q, x)
69
self.assertClose(q, x)
71
self.assertClose(q, x)
74
simple_real = [float(i) for i in xrange(-5, 6)]
75
simple_complex = [complex(x, y) for x in simple_real for y in simple_real]
76
for x in simple_complex:
77
for y in simple_complex:
80
# A naive complex division algorithm (such as in 2.0) is very prone to
81
# nonsense errors for these (overflows and underflows).
82
self.check_div(complex(1e200, 1e200), 1+0j)
83
self.check_div(complex(1e-200, 1e-200), 1+0j)
87
self.check_div(complex(random(), random()),
88
complex(random(), random()))
90
self.assertRaises(ZeroDivisionError, complex.__div__, 1+1j, 0+0j)
91
# FIXME: The following currently crashes on Alpha
92
# self.assertRaises(OverflowError, pow, 1e200+1j, 1e200+1j)
94
def test_truediv(self):
95
self.assertAlmostEqual(complex.__truediv__(2+0j, 1+1j), 1-1j)
96
self.assertRaises(ZeroDivisionError, complex.__truediv__, 1+1j, 0+0j)
98
def test_floordiv(self):
99
self.assertAlmostEqual(complex.__floordiv__(3+0j, 1.5+0j), 2)
100
self.assertRaises(ZeroDivisionError, complex.__floordiv__, 3+0j, 0+0j)
102
def test_coerce(self):
103
self.assertRaises(OverflowError, complex.__coerce__, 1+1j, 1L<<10000)
105
def test_richcompare(self):
106
self.assertRaises(OverflowError, complex.__eq__, 1+1j, 1L<<10000)
107
self.assertEqual(complex.__lt__(1+1j, None), NotImplemented)
108
self.assertIs(complex.__eq__(1+1j, 1+1j), True)
109
self.assertIs(complex.__eq__(1+1j, 2+2j), False)
110
self.assertIs(complex.__ne__(1+1j, 1+1j), False)
111
self.assertIs(complex.__ne__(1+1j, 2+2j), True)
112
self.assertRaises(TypeError, complex.__lt__, 1+1j, 2+2j)
113
self.assertRaises(TypeError, complex.__le__, 1+1j, 2+2j)
114
self.assertRaises(TypeError, complex.__gt__, 1+1j, 2+2j)
115
self.assertRaises(TypeError, complex.__ge__, 1+1j, 2+2j)
118
self.assertRaises(ZeroDivisionError, (1+1j).__mod__, 0+0j)
123
except ZeroDivisionError:
126
self.fail("modulo parama can't be 0")
128
def test_divmod(self):
129
self.assertRaises(ZeroDivisionError, divmod, 1+1j, 0+0j)
132
self.assertAlmostEqual(pow(1+1j, 0+0j), 1.0)
133
self.assertAlmostEqual(pow(0+0j, 2+0j), 0.0)
134
self.assertRaises(ZeroDivisionError, pow, 0+0j, 1j)
135
self.assertAlmostEqual(pow(1j, -1), 1/1j)
136
self.assertAlmostEqual(pow(1j, 200), 1)
137
self.assertRaises(ValueError, pow, 1+1j, 1+1j, 1+1j)
140
self.assertEqual(a ** 0j, 1)
141
self.assertEqual(a ** 0.+0.j, 1)
143
self.assertEqual(3j ** 0j, 1)
144
self.assertEqual(3j ** 0, 1)
148
except ZeroDivisionError:
151
self.fail("should fail 0.0 to negative or complex power")
155
except ZeroDivisionError:
158
self.fail("should fail 0.0 to negative or complex power")
160
# The following is used to exercise certain code paths
161
self.assertEqual(a ** 105, a ** 105)
162
self.assertEqual(a ** -105, a ** -105)
163
self.assertEqual(a ** -30, a ** -30)
165
self.assertEqual(0.0j ** 0, 1)
168
self.assertRaises(ValueError, pow, a, b, 0)
170
def test_boolcontext(self):
171
for i in xrange(100):
172
self.assert_(complex(random() + 1e-6, random() + 1e-6))
173
self.assert_(not complex(0.0, 0.0))
175
def test_conjugate(self):
176
self.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j)
178
def test_constructor(self):
180
def __init__(self, value): self.value = value
181
def __complex__(self): return self.value
183
def __init__(self, value): self.value = value
184
def __complex__(self): return self.value
185
self.assertEqual(complex(OS(1+10j)), 1+10j)
186
self.assertEqual(complex(NS(1+10j)), 1+10j)
187
self.assertRaises(TypeError, complex, OS(None))
188
self.assertRaises(TypeError, complex, NS(None))
190
self.assertAlmostEqual(complex("1+10j"), 1+10j)
191
self.assertAlmostEqual(complex(10), 10+0j)
192
self.assertAlmostEqual(complex(10.0), 10+0j)
193
self.assertAlmostEqual(complex(10L), 10+0j)
194
self.assertAlmostEqual(complex(10+0j), 10+0j)
195
self.assertAlmostEqual(complex(1,10), 1+10j)
196
self.assertAlmostEqual(complex(1,10L), 1+10j)
197
self.assertAlmostEqual(complex(1,10.0), 1+10j)
198
self.assertAlmostEqual(complex(1L,10), 1+10j)
199
self.assertAlmostEqual(complex(1L,10L), 1+10j)
200
self.assertAlmostEqual(complex(1L,10.0), 1+10j)
201
self.assertAlmostEqual(complex(1.0,10), 1+10j)
202
self.assertAlmostEqual(complex(1.0,10L), 1+10j)
203
self.assertAlmostEqual(complex(1.0,10.0), 1+10j)
204
self.assertAlmostEqual(complex(3.14+0j), 3.14+0j)
205
self.assertAlmostEqual(complex(3.14), 3.14+0j)
206
self.assertAlmostEqual(complex(314), 314.0+0j)
207
self.assertAlmostEqual(complex(314L), 314.0+0j)
208
self.assertAlmostEqual(complex(3.14+0j, 0j), 3.14+0j)
209
self.assertAlmostEqual(complex(3.14, 0.0), 3.14+0j)
210
self.assertAlmostEqual(complex(314, 0), 314.0+0j)
211
self.assertAlmostEqual(complex(314L, 0L), 314.0+0j)
212
self.assertAlmostEqual(complex(0j, 3.14j), -3.14+0j)
213
self.assertAlmostEqual(complex(0.0, 3.14j), -3.14+0j)
214
self.assertAlmostEqual(complex(0j, 3.14), 3.14j)
215
self.assertAlmostEqual(complex(0.0, 3.14), 3.14j)
216
self.assertAlmostEqual(complex("1"), 1+0j)
217
self.assertAlmostEqual(complex("1j"), 1j)
218
self.assertAlmostEqual(complex(), 0)
219
self.assertAlmostEqual(complex("-1"), -1)
220
self.assertAlmostEqual(complex("+1"), +1)
221
self.assertAlmostEqual(complex("(1+2j)"), 1+2j)
222
self.assertAlmostEqual(complex("(1.3+2.2j)"), 1.3+2.2j)
224
class complex2(complex): pass
225
self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j)
226
self.assertAlmostEqual(complex(real=17, imag=23), 17+23j)
227
self.assertAlmostEqual(complex(real=17+23j), 17+23j)
228
self.assertAlmostEqual(complex(real=17+23j, imag=23), 17+46j)
229
self.assertAlmostEqual(complex(real=1+2j, imag=3+4j), -3+5j)
231
# check that the sign of a zero in the real or imaginary part
232
# is preserved when constructing from two floats. (These checks
233
# are harmless on systems without support for signed zeros.)
235
"""Function that produces different results for 0. and -0."""
238
self.assertEqual(split_zeros(complex(1., 0.).imag), split_zeros(0.))
239
self.assertEqual(split_zeros(complex(1., -0.).imag), split_zeros(-0.))
240
self.assertEqual(split_zeros(complex(0., 1.).real), split_zeros(0.))
241
self.assertEqual(split_zeros(complex(-0., 1.).real), split_zeros(-0.))
244
self.assert_(complex(c) is c)
247
self.assertRaises(TypeError, complex, "1", "1")
248
self.assertRaises(TypeError, complex, 1, "1")
250
self.assertEqual(complex(" 3.14+J "), 3.14+1j)
251
if test_support.have_unicode:
252
self.assertEqual(complex(unicode(" 3.14+J ")), 3.14+1j)
254
# SF bug 543840: complex(string) accepts strings with \0
256
self.assertRaises(ValueError, complex, '1+1j\0j')
258
self.assertRaises(TypeError, int, 5+3j)
259
self.assertRaises(TypeError, long, 5+3j)
260
self.assertRaises(TypeError, float, 5+3j)
261
self.assertRaises(ValueError, complex, "")
262
self.assertRaises(TypeError, complex, None)
263
self.assertRaises(ValueError, complex, "\0")
264
self.assertRaises(ValueError, complex, "3\09")
265
self.assertRaises(TypeError, complex, "1", "2")
266
self.assertRaises(TypeError, complex, "1", 42)
267
self.assertRaises(TypeError, complex, 1, "2")
268
self.assertRaises(ValueError, complex, "1+")
269
self.assertRaises(ValueError, complex, "1+1j+1j")
270
self.assertRaises(ValueError, complex, "--")
271
self.assertRaises(ValueError, complex, "(1+2j")
272
self.assertRaises(ValueError, complex, "1+2j)")
273
self.assertRaises(ValueError, complex, "1+(2j)")
274
self.assertRaises(ValueError, complex, "(1+2j)123")
275
if test_support.have_unicode:
276
self.assertRaises(ValueError, complex, unicode("1"*500))
277
self.assertRaises(ValueError, complex, unicode("x"))
279
class EvilExc(Exception):
283
def __complex__(self):
286
self.assertRaises(EvilExc, complex, evilcomplex())
289
def __init__(self, value):
294
self.assertAlmostEqual(complex(float2(42.)), 42)
295
self.assertAlmostEqual(complex(real=float2(17.), imag=float2(23.)), 17+23j)
296
self.assertRaises(TypeError, complex, float2(None))
298
class complex0(complex):
299
"""Test usage of __complex__() when inheriting from 'complex'"""
300
def __complex__(self):
303
class complex1(complex):
304
"""Test usage of __complex__() with a __new__() method"""
305
def __new__(self, value=0j):
306
return complex.__new__(self, 2*value)
307
def __complex__(self):
310
class complex2(complex):
311
"""Make sure that __complex__() calls fail if anything other than a
312
complex is returned"""
313
def __complex__(self):
316
self.assertAlmostEqual(complex(complex0(1j)), 42j)
317
self.assertAlmostEqual(complex(complex1(1j)), 2j)
318
self.assertRaises(TypeError, complex, complex2(1j))
321
for x in xrange(-30, 30):
322
self.assertEqual(hash(x), hash(complex(x, 0)))
323
x /= 3.0 # now check against floating point
324
self.assertEqual(hash(x), hash(complex(x, 0.)))
327
nums = [complex(x/3., y/7.) for x in xrange(-9,9) for y in xrange(-9,9)]
329
self.assertAlmostEqual((num.real**2 + num.imag**2) ** 0.5, abs(num))
332
self.assertEqual(repr(1+6j), '(1+6j)')
333
self.assertEqual(repr(1-6j), '(1-6j)')
335
self.assertNotEqual(repr(-(1+0j)), '(-1+-0j)')
337
self.assertEqual(1-6j,complex(repr(1-6j)))
338
self.assertEqual(1+6j,complex(repr(1+6j)))
339
self.assertEqual(-6j,complex(repr(-6j)))
340
self.assertEqual(6j,complex(repr(6j)))
342
self.assertEqual(repr(complex(1., INF)), "(1+inf*j)")
343
self.assertEqual(repr(complex(1., -INF)), "(1-inf*j)")
344
self.assertEqual(repr(complex(INF, 1)), "(inf+1j)")
345
self.assertEqual(repr(complex(-INF, INF)), "(-inf+inf*j)")
346
self.assertEqual(repr(complex(NAN, 1)), "(nan+1j)")
347
self.assertEqual(repr(complex(1, NAN)), "(1+nan*j)")
348
self.assertEqual(repr(complex(NAN, NAN)), "(nan+nan*j)")
350
self.assertEqual(repr(complex(0, INF)), "inf*j")
351
self.assertEqual(repr(complex(0, -INF)), "-inf*j")
352
self.assertEqual(repr(complex(0, NAN)), "nan*j")
355
self.assertEqual(-(1+6j), -1-6j)
363
fo = open(test_support.TESTFN, "wb")
366
fo = open(test_support.TESTFN, "rb")
367
self.assertEqual(fo.read(), "%s %s\n" % (a, b))
369
if (fo is not None) and (not fo.closed):
372
os.remove(test_support.TESTFN)
373
except (OSError, IOError):
376
def test_getnewargs(self):
377
self.assertEqual((1+2j).__getnewargs__(), (1.0, 2.0))
378
self.assertEqual((1-2j).__getnewargs__(), (1.0, -2.0))
379
self.assertEqual((2j).__getnewargs__(), (0.0, 2.0))
380
self.assertEqual((-0j).__getnewargs__(), (0.0, -0.0))
381
self.assertEqual(complex(0, INF).__getnewargs__(), (0.0, INF))
382
self.assertEqual(complex(INF, 0).__getnewargs__(), (INF, 0.0))
384
if float.__getformat__("double").startswith("IEEE"):
385
def test_plus_minus_0j(self):
386
# test that -0j and 0j literals are not identified
388
self.assertEquals(atan2(z1.imag, -1.), atan2(0., -1.))
389
self.assertEquals(atan2(z2.imag, -1.), atan2(-0., -1.))
392
test_support.run_unittest(ComplexTest)
394
if __name__ == "__main__":