blob: 91f074b8cabe8f8630e23845c6e38481d472a574 [file] [log] [blame]
Walter Dörwald5301d9c2003-08-05 15:55:38 +00001import unittest, os
Walter Dörwald5edd7852003-06-18 14:26:18 +00002from test import test_support
3
4import warnings
5warnings.filterwarnings(
6 "ignore",
7 category=DeprecationWarning,
8 message=".*complex divmod.*are deprecated"
9)
10
Tim Peters0f336042001-03-18 08:21:57 +000011from random import random
12
Walter Dörwald5edd7852003-06-18 14:26:18 +000013# These tests ensure that complex math does the right thing
Fred Drake68773e72001-12-13 19:57:53 +000014
Walter Dörwald5edd7852003-06-18 14:26:18 +000015class ComplexTest(unittest.TestCase):
Tim Peters0f336042001-03-18 08:21:57 +000016
Walter Dörwald5edd7852003-06-18 14:26:18 +000017 def assertAlmostEqual(self, a, b):
18 if isinstance(a, complex):
19 if isinstance(b, complex):
20 unittest.TestCase.assertAlmostEqual(self, a.real, b.real)
21 unittest.TestCase.assertAlmostEqual(self, a.imag, b.imag)
22 else:
23 unittest.TestCase.assertAlmostEqual(self, a.real, b)
24 unittest.TestCase.assertAlmostEqual(self, a.imag, 0.)
25 else:
26 if isinstance(b, complex):
27 unittest.TestCase.assertAlmostEqual(self, a, b.real)
28 unittest.TestCase.assertAlmostEqual(self, 0., b.imag)
29 else:
30 unittest.TestCase.assertAlmostEqual(self, a, b)
Tim Peters0f336042001-03-18 08:21:57 +000031
Walter Dörwald5edd7852003-06-18 14:26:18 +000032 def assertCloseAbs(self, x, y, eps=1e-9):
33 """Return true iff floats x and y "are close\""""
34 # put the one with larger magnitude second
35 if abs(x) > abs(y):
36 x, y = y, x
37 if y == 0:
38 return abs(x) < eps
39 if x == 0:
40 return abs(y) < eps
41 # check that relative difference < eps
42 self.assert_(abs((x-y)/y) < eps)
Tim Petersc5b235c2001-09-06 23:00:21 +000043
Walter Dörwald5edd7852003-06-18 14:26:18 +000044 def assertClose(self, x, y, eps=1e-9):
45 """Return true iff complexes x and y "are close\""""
46 self.assertCloseAbs(x.real, y.real, eps)
47 self.assertCloseAbs(x.imag, y.imag, eps)
Tim Peters0f336042001-03-18 08:21:57 +000048
Walter Dörwald5edd7852003-06-18 14:26:18 +000049 def assertIs(self, a, b):
50 self.assert_(a is b)
Tim Peters0f336042001-03-18 08:21:57 +000051
Walter Dörwald5edd7852003-06-18 14:26:18 +000052 def check_div(self, x, y):
53 """Compute complex z=x*y, and check that z/x==y and z/y==x."""
54 z = x * y
55 if x != 0:
56 q = z / x
57 self.assertClose(q, y)
Walter Dörwaldb27cca62003-08-05 15:34:34 +000058 q = z.__truediv__(x)
59 self.assertClose(q, y)
Walter Dörwald5edd7852003-06-18 14:26:18 +000060 if y != 0:
61 q = z / y
62 self.assertClose(q, x)
Walter Dörwaldb27cca62003-08-05 15:34:34 +000063 q = z.__truediv__(y)
64 self.assertClose(q, x)
Tim Peters0f336042001-03-18 08:21:57 +000065
Neal Norwitzbcc0db82006-03-24 08:14:36 +000066 def test_truediv(self):
Walter Dörwald5edd7852003-06-18 14:26:18 +000067 simple_real = [float(i) for i in xrange(-5, 6)]
68 simple_complex = [complex(x, y) for x in simple_real for y in simple_real]
69 for x in simple_complex:
70 for y in simple_complex:
71 self.check_div(x, y)
Tim Peters0f336042001-03-18 08:21:57 +000072
Walter Dörwald5edd7852003-06-18 14:26:18 +000073 # A naive complex division algorithm (such as in 2.0) is very prone to
74 # nonsense errors for these (overflows and underflows).
75 self.check_div(complex(1e200, 1e200), 1+0j)
76 self.check_div(complex(1e-200, 1e-200), 1+0j)
Tim Peters0f336042001-03-18 08:21:57 +000077
Walter Dörwald5edd7852003-06-18 14:26:18 +000078 # Just for fun.
79 for i in xrange(100):
80 self.check_div(complex(random(), random()),
81 complex(random(), random()))
Neal Norwitzfc37af82001-12-29 01:02:21 +000082
Neal Norwitzbcc0db82006-03-24 08:14:36 +000083 self.assertRaises(ZeroDivisionError, complex.__truediv__, 1+1j, 0+0j)
Walter Dörwald5edd7852003-06-18 14:26:18 +000084 # FIXME: The following currently crashes on Alpha
85 # self.assertRaises(OverflowError, pow, 1e200+1j, 1e200+1j)
Neal Norwitzfc37af82001-12-29 01:02:21 +000086
Walter Dörwald5edd7852003-06-18 14:26:18 +000087 def test_truediv(self):
88 self.assertAlmostEqual(complex.__truediv__(2+0j, 1+1j), 1-1j)
89 self.assertRaises(ZeroDivisionError, complex.__truediv__, 1+1j, 0+0j)
Neal Norwitz5a0f0102001-12-29 14:31:46 +000090
Walter Dörwald5edd7852003-06-18 14:26:18 +000091 def test_floordiv(self):
92 self.assertAlmostEqual(complex.__floordiv__(3+0j, 1.5+0j), 2)
93 self.assertRaises(ZeroDivisionError, complex.__floordiv__, 3+0j, 0+0j)
Neal Norwitzfc37af82001-12-29 01:02:21 +000094
Walter Dörwald5edd7852003-06-18 14:26:18 +000095 def test_richcompare(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +000096 self.assertRaises(OverflowError, complex.__eq__, 1+1j, 1<<10000)
Walter Dörwald5edd7852003-06-18 14:26:18 +000097 self.assertEqual(complex.__lt__(1+1j, None), NotImplemented)
98 self.assertIs(complex.__eq__(1+1j, 1+1j), True)
99 self.assertIs(complex.__eq__(1+1j, 2+2j), False)
100 self.assertIs(complex.__ne__(1+1j, 1+1j), False)
101 self.assertIs(complex.__ne__(1+1j, 2+2j), True)
102 self.assertRaises(TypeError, complex.__lt__, 1+1j, 2+2j)
103 self.assertRaises(TypeError, complex.__le__, 1+1j, 2+2j)
104 self.assertRaises(TypeError, complex.__gt__, 1+1j, 2+2j)
105 self.assertRaises(TypeError, complex.__ge__, 1+1j, 2+2j)
Tim Peters0f336042001-03-18 08:21:57 +0000106
Walter Dörwald5edd7852003-06-18 14:26:18 +0000107 def test_mod(self):
108 self.assertRaises(ZeroDivisionError, (1+1j).__mod__, 0+0j)
109
Walter Dörwaldf393fc62003-07-15 18:47:27 +0000110 a = 3.33+4.43j
111 try:
112 a % 0
113 except ZeroDivisionError:
114 pass
115 else:
116 self.fail("modulo parama can't be 0")
117
Walter Dörwald5edd7852003-06-18 14:26:18 +0000118 def test_divmod(self):
119 self.assertRaises(ZeroDivisionError, divmod, 1+1j, 0+0j)
120
121 def test_pow(self):
122 self.assertAlmostEqual(pow(1+1j, 0+0j), 1.0)
123 self.assertAlmostEqual(pow(0+0j, 2+0j), 0.0)
124 self.assertRaises(ZeroDivisionError, pow, 0+0j, 1j)
125 self.assertAlmostEqual(pow(1j, -1), 1/1j)
126 self.assertAlmostEqual(pow(1j, 200), 1)
127 self.assertRaises(ValueError, pow, 1+1j, 1+1j, 1+1j)
128
Walter Dörwaldf393fc62003-07-15 18:47:27 +0000129 a = 3.33+4.43j
130 self.assertEqual(a ** 0j, 1)
131 self.assertEqual(a ** 0.+0.j, 1)
132
133 self.assertEqual(3j ** 0j, 1)
134 self.assertEqual(3j ** 0, 1)
135
136 try:
137 0j ** a
138 except ZeroDivisionError:
139 pass
140 else:
141 self.fail("should fail 0.0 to negative or complex power")
142
143 try:
144 0j ** (3-2j)
145 except ZeroDivisionError:
146 pass
147 else:
148 self.fail("should fail 0.0 to negative or complex power")
149
150 # The following is used to exercise certain code paths
151 self.assertEqual(a ** 105, a ** 105)
152 self.assertEqual(a ** -105, a ** -105)
153 self.assertEqual(a ** -30, a ** -30)
154
155 self.assertEqual(0.0j ** 0, 1)
156
157 b = 5.1+2.3j
158 self.assertRaises(ValueError, pow, a, b, 0)
159
Walter Dörwald5edd7852003-06-18 14:26:18 +0000160 def test_boolcontext(self):
161 for i in xrange(100):
162 self.assert_(complex(random() + 1e-6, random() + 1e-6))
163 self.assert_(not complex(0.0, 0.0))
164
165 def test_conjugate(self):
166 self.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j)
167
168 def test_constructor(self):
169 class OS:
170 def __init__(self, value): self.value = value
171 def __complex__(self): return self.value
172 class NS(object):
173 def __init__(self, value): self.value = value
174 def __complex__(self): return self.value
175 self.assertEqual(complex(OS(1+10j)), 1+10j)
176 self.assertEqual(complex(NS(1+10j)), 1+10j)
177 self.assertRaises(TypeError, complex, OS(None))
178 self.assertRaises(TypeError, complex, NS(None))
179
180 self.assertAlmostEqual(complex("1+10j"), 1+10j)
181 self.assertAlmostEqual(complex(10), 10+0j)
182 self.assertAlmostEqual(complex(10.0), 10+0j)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000183 self.assertAlmostEqual(complex(10), 10+0j)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000184 self.assertAlmostEqual(complex(10+0j), 10+0j)
185 self.assertAlmostEqual(complex(1,10), 1+10j)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000186 self.assertAlmostEqual(complex(1,10), 1+10j)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000187 self.assertAlmostEqual(complex(1,10.0), 1+10j)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000188 self.assertAlmostEqual(complex(1,10), 1+10j)
189 self.assertAlmostEqual(complex(1,10), 1+10j)
190 self.assertAlmostEqual(complex(1,10.0), 1+10j)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000191 self.assertAlmostEqual(complex(1.0,10), 1+10j)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000192 self.assertAlmostEqual(complex(1.0,10), 1+10j)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000193 self.assertAlmostEqual(complex(1.0,10.0), 1+10j)
194 self.assertAlmostEqual(complex(3.14+0j), 3.14+0j)
195 self.assertAlmostEqual(complex(3.14), 3.14+0j)
196 self.assertAlmostEqual(complex(314), 314.0+0j)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000197 self.assertAlmostEqual(complex(314), 314.0+0j)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000198 self.assertAlmostEqual(complex(3.14+0j, 0j), 3.14+0j)
199 self.assertAlmostEqual(complex(3.14, 0.0), 3.14+0j)
200 self.assertAlmostEqual(complex(314, 0), 314.0+0j)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000201 self.assertAlmostEqual(complex(314, 0), 314.0+0j)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000202 self.assertAlmostEqual(complex(0j, 3.14j), -3.14+0j)
203 self.assertAlmostEqual(complex(0.0, 3.14j), -3.14+0j)
204 self.assertAlmostEqual(complex(0j, 3.14), 3.14j)
205 self.assertAlmostEqual(complex(0.0, 3.14), 3.14j)
206 self.assertAlmostEqual(complex("1"), 1+0j)
207 self.assertAlmostEqual(complex("1j"), 1j)
208 self.assertAlmostEqual(complex(), 0)
209 self.assertAlmostEqual(complex("-1"), -1)
210 self.assertAlmostEqual(complex("+1"), +1)
211
212 class complex2(complex): pass
213 self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j)
214 self.assertAlmostEqual(complex(real=17, imag=23), 17+23j)
215 self.assertAlmostEqual(complex(real=17+23j), 17+23j)
216 self.assertAlmostEqual(complex(real=17+23j, imag=23), 17+46j)
217 self.assertAlmostEqual(complex(real=1+2j, imag=3+4j), -3+5j)
218
219 c = 3.14 + 1j
220 self.assert_(complex(c) is c)
221 del c
222
223 self.assertRaises(TypeError, complex, "1", "1")
224 self.assertRaises(TypeError, complex, 1, "1")
225
226 self.assertEqual(complex(" 3.14+J "), 3.14+1j)
227 if test_support.have_unicode:
228 self.assertEqual(complex(unicode(" 3.14+J ")), 3.14+1j)
229
230 # SF bug 543840: complex(string) accepts strings with \0
231 # Fixed in 2.3.
232 self.assertRaises(ValueError, complex, '1+1j\0j')
233
234 self.assertRaises(TypeError, int, 5+3j)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000235 self.assertRaises(TypeError, int, 5+3j)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000236 self.assertRaises(TypeError, float, 5+3j)
237 self.assertRaises(ValueError, complex, "")
238 self.assertRaises(TypeError, complex, None)
239 self.assertRaises(ValueError, complex, "\0")
240 self.assertRaises(TypeError, complex, "1", "2")
241 self.assertRaises(TypeError, complex, "1", 42)
242 self.assertRaises(TypeError, complex, 1, "2")
243 self.assertRaises(ValueError, complex, "1+")
244 self.assertRaises(ValueError, complex, "1+1j+1j")
245 self.assertRaises(ValueError, complex, "--")
246 if test_support.have_unicode:
247 self.assertRaises(ValueError, complex, unicode("1"*500))
248 self.assertRaises(ValueError, complex, unicode("x"))
249
250 class EvilExc(Exception):
Tim Peters478c1052003-06-29 05:46:54 +0000251 pass
Walter Dörwald5edd7852003-06-18 14:26:18 +0000252
253 class evilcomplex:
254 def __complex__(self):
255 raise EvilExc
256
257 self.assertRaises(EvilExc, complex, evilcomplex())
258
259 class float2:
260 def __init__(self, value):
261 self.value = value
262 def __float__(self):
263 return self.value
264
265 self.assertAlmostEqual(complex(float2(42.)), 42)
266 self.assertAlmostEqual(complex(real=float2(17.), imag=float2(23.)), 17+23j)
267 self.assertRaises(TypeError, complex, float2(None))
268
Brett Cannonc3647ac2005-04-26 03:45:26 +0000269 class complex0(complex):
270 """Test usage of __complex__() when inheriting from 'complex'"""
271 def __complex__(self):
272 return 42j
273
274 class complex1(complex):
275 """Test usage of __complex__() with a __new__() method"""
276 def __new__(self, value=0j):
277 return complex.__new__(self, 2*value)
278 def __complex__(self):
279 return self
280
281 class complex2(complex):
282 """Make sure that __complex__() calls fail if anything other than a
283 complex is returned"""
284 def __complex__(self):
285 return None
286
287 self.assertAlmostEqual(complex(complex0(1j)), 42j)
288 self.assertAlmostEqual(complex(complex1(1j)), 2j)
289 self.assertRaises(TypeError, complex, complex2(1j))
290
Walter Dörwald5edd7852003-06-18 14:26:18 +0000291 def test_hash(self):
292 for x in xrange(-30, 30):
293 self.assertEqual(hash(x), hash(complex(x, 0)))
294 x /= 3.0 # now check against floating point
295 self.assertEqual(hash(x), hash(complex(x, 0.)))
296
297 def test_abs(self):
298 nums = [complex(x/3., y/7.) for x in xrange(-9,9) for y in xrange(-9,9)]
299 for num in nums:
300 self.assertAlmostEqual((num.real**2 + num.imag**2) ** 0.5, abs(num))
301
302 def test_repr(self):
303 self.assertEqual(repr(1+6j), '(1+6j)')
Martin v. Löwis70aa1f22004-08-22 21:09:15 +0000304 self.assertEqual(repr(1-6j), '(1-6j)')
Walter Dörwald5edd7852003-06-18 14:26:18 +0000305
Georg Brandl9e281072005-09-17 07:51:15 +0000306 self.assertNotEqual(repr(-(1+0j)), '(-1+-0j)')
307
Walter Dörwald5edd7852003-06-18 14:26:18 +0000308 def test_neg(self):
309 self.assertEqual(-(1+6j), -1-6j)
310
Walter Dörwaldf393fc62003-07-15 18:47:27 +0000311 def test_file(self):
312 a = 3.33+4.43j
313 b = 5.1+2.3j
314
315 fo = None
316 try:
317 fo = open(test_support.TESTFN, "wb")
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000318 print(a, b, file=fo)
Walter Dörwaldf393fc62003-07-15 18:47:27 +0000319 fo.close()
320 fo = open(test_support.TESTFN, "rb")
321 self.assertEqual(fo.read(), "%s %s\n" % (a, b))
322 finally:
323 if (fo is not None) and (not fo.closed):
324 fo.close()
325 try:
326 os.remove(test_support.TESTFN)
327 except (OSError, IOError):
328 pass
Walter Dörwald5edd7852003-06-18 14:26:18 +0000329
330def test_main():
331 test_support.run_unittest(ComplexTest)
332
333if __name__ == "__main__":
334 test_main()