2
from test import support
4
from random import random
9
# These tests ensure that complex math does the right thing
11
class ComplexTest(unittest.TestCase):
13
def assertAlmostEqual(self, a, b):
14
if isinstance(a, complex):
15
if isinstance(b, complex):
16
unittest.TestCase.assertAlmostEqual(self, a.real, b.real)
17
unittest.TestCase.assertAlmostEqual(self, a.imag, b.imag)
19
unittest.TestCase.assertAlmostEqual(self, a.real, b)
20
unittest.TestCase.assertAlmostEqual(self, a.imag, 0.)
22
if isinstance(b, complex):
23
unittest.TestCase.assertAlmostEqual(self, a, b.real)
24
unittest.TestCase.assertAlmostEqual(self, 0., b.imag)
26
unittest.TestCase.assertAlmostEqual(self, a, b)
28
def assertCloseAbs(self, x, y, eps=1e-9):
29
"""Return true iff floats x and y "are close\""""
30
# put the one with larger magnitude second
37
# check that relative difference < eps
38
self.assert_(abs((x-y)/y) < eps)
40
def assertClose(self, x, y, eps=1e-9):
41
"""Return true iff complexes x and y "are close\""""
42
self.assertCloseAbs(x.real, y.real, eps)
43
self.assertCloseAbs(x.imag, y.imag, eps)
45
def assertIs(self, a, b):
48
def check_div(self, x, y):
49
"""Compute complex z=x*y, and check that z/x==y and z/y==x."""
53
self.assertClose(q, y)
55
self.assertClose(q, y)
58
self.assertClose(q, x)
60
self.assertClose(q, x)
62
def test_truediv(self):
63
simple_real = [float(i) for i in range(-5, 6)]
64
simple_complex = [complex(x, y) for x in simple_real for y in simple_real]
65
for x in simple_complex:
66
for y in simple_complex:
69
# A naive complex division algorithm (such as in 2.0) is very prone to
70
# nonsense errors for these (overflows and underflows).
71
self.check_div(complex(1e200, 1e200), 1+0j)
72
self.check_div(complex(1e-200, 1e-200), 1+0j)
76
self.check_div(complex(random(), random()),
77
complex(random(), random()))
79
self.assertRaises(ZeroDivisionError, complex.__truediv__, 1+1j, 0+0j)
80
# FIXME: The following currently crashes on Alpha
81
# self.assertRaises(OverflowError, pow, 1e200+1j, 1e200+1j)
83
def test_truediv(self):
84
self.assertAlmostEqual(complex.__truediv__(2+0j, 1+1j), 1-1j)
85
self.assertRaises(ZeroDivisionError, complex.__truediv__, 1+1j, 0+0j)
87
def test_floordiv(self):
88
self.assertRaises(TypeError, complex.__floordiv__, 3+0j, 1.5+0j)
89
self.assertRaises(TypeError, complex.__floordiv__, 3+0j, 0+0j)
91
def test_richcompare(self):
92
self.assertRaises(OverflowError, complex.__eq__, 1+1j, 1<<10000)
93
self.assertEqual(complex.__lt__(1+1j, None), NotImplemented)
94
self.assertIs(complex.__eq__(1+1j, 1+1j), True)
95
self.assertIs(complex.__eq__(1+1j, 2+2j), False)
96
self.assertIs(complex.__ne__(1+1j, 1+1j), False)
97
self.assertIs(complex.__ne__(1+1j, 2+2j), True)
98
self.assertRaises(TypeError, complex.__lt__, 1+1j, 2+2j)
99
self.assertRaises(TypeError, complex.__le__, 1+1j, 2+2j)
100
self.assertRaises(TypeError, complex.__gt__, 1+1j, 2+2j)
101
self.assertRaises(TypeError, complex.__ge__, 1+1j, 2+2j)
104
# % is no longer supported on complex numbers
105
self.assertRaises(TypeError, (1+1j).__mod__, 0+0j)
106
self.assertRaises(TypeError, lambda: (3.33+4.43j) % 0)
107
self.assertRaises(TypeError, (1+1j).__mod__, 4.3j)
109
def test_divmod(self):
110
self.assertRaises(TypeError, divmod, 1+1j, 1+0j)
111
self.assertRaises(TypeError, divmod, 1+1j, 0+0j)
114
self.assertAlmostEqual(pow(1+1j, 0+0j), 1.0)
115
self.assertAlmostEqual(pow(0+0j, 2+0j), 0.0)
116
self.assertRaises(ZeroDivisionError, pow, 0+0j, 1j)
117
self.assertAlmostEqual(pow(1j, -1), 1/1j)
118
self.assertAlmostEqual(pow(1j, 200), 1)
119
self.assertRaises(ValueError, pow, 1+1j, 1+1j, 1+1j)
122
self.assertEqual(a ** 0j, 1)
123
self.assertEqual(a ** 0.+0.j, 1)
125
self.assertEqual(3j ** 0j, 1)
126
self.assertEqual(3j ** 0, 1)
130
except ZeroDivisionError:
133
self.fail("should fail 0.0 to negative or complex power")
137
except ZeroDivisionError:
140
self.fail("should fail 0.0 to negative or complex power")
142
# The following is used to exercise certain code paths
143
self.assertEqual(a ** 105, a ** 105)
144
self.assertEqual(a ** -105, a ** -105)
145
self.assertEqual(a ** -30, a ** -30)
147
self.assertEqual(0.0j ** 0, 1)
150
self.assertRaises(ValueError, pow, a, b, 0)
152
def test_boolcontext(self):
154
self.assert_(complex(random() + 1e-6, random() + 1e-6))
155
self.assert_(not complex(0.0, 0.0))
157
def test_conjugate(self):
158
self.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j)
160
def test_constructor(self):
162
def __init__(self, value): self.value = value
163
def __complex__(self): return self.value
165
def __init__(self, value): self.value = value
166
def __complex__(self): return self.value
167
self.assertEqual(complex(OS(1+10j)), 1+10j)
168
self.assertEqual(complex(NS(1+10j)), 1+10j)
169
self.assertRaises(TypeError, complex, OS(None))
170
self.assertRaises(TypeError, complex, NS(None))
172
self.assertAlmostEqual(complex("1+10j"), 1+10j)
173
self.assertAlmostEqual(complex(10), 10+0j)
174
self.assertAlmostEqual(complex(10.0), 10+0j)
175
self.assertAlmostEqual(complex(10), 10+0j)
176
self.assertAlmostEqual(complex(10+0j), 10+0j)
177
self.assertAlmostEqual(complex(1,10), 1+10j)
178
self.assertAlmostEqual(complex(1,10), 1+10j)
179
self.assertAlmostEqual(complex(1,10.0), 1+10j)
180
self.assertAlmostEqual(complex(1,10), 1+10j)
181
self.assertAlmostEqual(complex(1,10), 1+10j)
182
self.assertAlmostEqual(complex(1,10.0), 1+10j)
183
self.assertAlmostEqual(complex(1.0,10), 1+10j)
184
self.assertAlmostEqual(complex(1.0,10), 1+10j)
185
self.assertAlmostEqual(complex(1.0,10.0), 1+10j)
186
self.assertAlmostEqual(complex(3.14+0j), 3.14+0j)
187
self.assertAlmostEqual(complex(3.14), 3.14+0j)
188
self.assertAlmostEqual(complex(314), 314.0+0j)
189
self.assertAlmostEqual(complex(314), 314.0+0j)
190
self.assertAlmostEqual(complex(3.14+0j, 0j), 3.14+0j)
191
self.assertAlmostEqual(complex(3.14, 0.0), 3.14+0j)
192
self.assertAlmostEqual(complex(314, 0), 314.0+0j)
193
self.assertAlmostEqual(complex(314, 0), 314.0+0j)
194
self.assertAlmostEqual(complex(0j, 3.14j), -3.14+0j)
195
self.assertAlmostEqual(complex(0.0, 3.14j), -3.14+0j)
196
self.assertAlmostEqual(complex(0j, 3.14), 3.14j)
197
self.assertAlmostEqual(complex(0.0, 3.14), 3.14j)
198
self.assertAlmostEqual(complex("1"), 1+0j)
199
self.assertAlmostEqual(complex("1j"), 1j)
200
self.assertAlmostEqual(complex(), 0)
201
self.assertAlmostEqual(complex("-1"), -1)
202
self.assertAlmostEqual(complex("+1"), +1)
203
self.assertAlmostEqual(complex("(1+2j)"), 1+2j)
204
self.assertAlmostEqual(complex("(1.3+2.2j)"), 1.3+2.2j)
206
class complex2(complex): pass
207
self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j)
208
self.assertAlmostEqual(complex(real=17, imag=23), 17+23j)
209
self.assertAlmostEqual(complex(real=17+23j), 17+23j)
210
self.assertAlmostEqual(complex(real=17+23j, imag=23), 17+46j)
211
self.assertAlmostEqual(complex(real=1+2j, imag=3+4j), -3+5j)
213
# check that the sign of a zero in the real or imaginary part
214
# is preserved when constructing from two floats. (These checks
215
# are harmless on systems without support for signed zeros.)
217
"""Function that produces different results for 0. and -0."""
220
self.assertEqual(split_zeros(complex(1., 0.).imag), split_zeros(0.))
221
self.assertEqual(split_zeros(complex(1., -0.).imag), split_zeros(-0.))
222
self.assertEqual(split_zeros(complex(0., 1.).real), split_zeros(0.))
223
self.assertEqual(split_zeros(complex(-0., 1.).real), split_zeros(-0.))
226
self.assert_(complex(c) is c)
229
self.assertRaises(TypeError, complex, "1", "1")
230
self.assertRaises(TypeError, complex, 1, "1")
232
self.assertEqual(complex(" 3.14+J "), 3.14+1j)
234
# SF bug 543840: complex(string) accepts strings with \0
236
self.assertRaises(ValueError, complex, '1+1j\0j')
238
self.assertRaises(TypeError, int, 5+3j)
239
self.assertRaises(TypeError, int, 5+3j)
240
self.assertRaises(TypeError, float, 5+3j)
241
self.assertRaises(ValueError, complex, "")
242
self.assertRaises(TypeError, complex, None)
243
self.assertRaises(ValueError, complex, "\0")
244
self.assertRaises(ValueError, complex, "3\09")
245
self.assertRaises(TypeError, complex, "1", "2")
246
self.assertRaises(TypeError, complex, "1", 42)
247
self.assertRaises(TypeError, complex, 1, "2")
248
self.assertRaises(ValueError, complex, "1+")
249
self.assertRaises(ValueError, complex, "1+1j+1j")
250
self.assertRaises(ValueError, complex, "--")
251
self.assertRaises(ValueError, complex, "(1+2j")
252
self.assertRaises(ValueError, complex, "1+2j)")
253
self.assertRaises(ValueError, complex, "1+(2j)")
254
self.assertRaises(ValueError, complex, "(1+2j)123")
255
self.assertRaises(ValueError, complex, "1"*500)
256
self.assertRaises(ValueError, complex, "x")
258
class EvilExc(Exception):
262
def __complex__(self):
265
self.assertRaises(EvilExc, complex, evilcomplex())
268
def __init__(self, value):
273
self.assertAlmostEqual(complex(float2(42.)), 42)
274
self.assertAlmostEqual(complex(real=float2(17.), imag=float2(23.)), 17+23j)
275
self.assertRaises(TypeError, complex, float2(None))
277
class complex0(complex):
278
"""Test usage of __complex__() when inheriting from 'complex'"""
279
def __complex__(self):
282
class complex1(complex):
283
"""Test usage of __complex__() with a __new__() method"""
284
def __new__(self, value=0j):
285
return complex.__new__(self, 2*value)
286
def __complex__(self):
289
class complex2(complex):
290
"""Make sure that __complex__() calls fail if anything other than a
291
complex is returned"""
292
def __complex__(self):
295
self.assertAlmostEqual(complex(complex0(1j)), 42j)
296
self.assertAlmostEqual(complex(complex1(1j)), 2j)
297
self.assertRaises(TypeError, complex, complex2(1j))
300
for x in range(-30, 30):
301
self.assertEqual(hash(x), hash(complex(x, 0)))
302
x /= 3.0 # now check against floating point
303
self.assertEqual(hash(x), hash(complex(x, 0.)))
306
nums = [complex(x/3., y/7.) for x in range(-9,9) for y in range(-9,9)]
308
self.assertAlmostEqual((num.real**2 + num.imag**2) ** 0.5, abs(num))
311
self.assertEqual(repr(1+6j), '(1+6j)')
312
self.assertEqual(repr(1-6j), '(1-6j)')
314
self.assertNotEqual(repr(-(1+0j)), '(-1+-0j)')
316
self.assertEqual(1-6j,complex(repr(1-6j)))
317
self.assertEqual(1+6j,complex(repr(1+6j)))
318
self.assertEqual(-6j,complex(repr(-6j)))
319
self.assertEqual(6j,complex(repr(6j)))
321
self.assertEqual(repr(complex(1., INF)), "(1+inf*j)")
322
self.assertEqual(repr(complex(1., -INF)), "(1-inf*j)")
323
self.assertEqual(repr(complex(INF, 1)), "(inf+1j)")
324
self.assertEqual(repr(complex(-INF, INF)), "(-inf+inf*j)")
325
self.assertEqual(repr(complex(NAN, 1)), "(nan+1j)")
326
self.assertEqual(repr(complex(1, NAN)), "(1+nan*j)")
327
self.assertEqual(repr(complex(NAN, NAN)), "(nan+nan*j)")
329
self.assertEqual(repr(complex(0, INF)), "inf*j")
330
self.assertEqual(repr(complex(0, -INF)), "-inf*j")
331
self.assertEqual(repr(complex(0, NAN)), "nan*j")
334
self.assertEqual(-(1+6j), -1-6j)
342
fo = open(support.TESTFN, "w")
345
fo = open(support.TESTFN, "r")
346
self.assertEqual(fo.read(), ("%s %s\n" % (a, b)))
348
if (fo is not None) and (not fo.closed):
351
os.remove(support.TESTFN)
352
except (OSError, IOError):
355
def test_getnewargs(self):
356
self.assertEqual((1+2j).__getnewargs__(), (1.0, 2.0))
357
self.assertEqual((1-2j).__getnewargs__(), (1.0, -2.0))
358
self.assertEqual((2j).__getnewargs__(), (0.0, 2.0))
359
self.assertEqual((-0j).__getnewargs__(), (0.0, -0.0))
360
self.assertEqual(complex(0, INF).__getnewargs__(), (0.0, INF))
361
self.assertEqual(complex(INF, 0).__getnewargs__(), (INF, 0.0))
363
if float.__getformat__("double").startswith("IEEE"):
364
def test_plus_minus_0j(self):
365
# test that -0j and 0j literals are not identified
367
self.assertEquals(atan2(z1.imag, -1.), atan2(0., -1.))
368
self.assertEquals(atan2(z2.imag, -1.), atan2(-0., -1.))
371
support.run_unittest(ComplexTest)
373
if __name__ == "__main__":