~malept/ubuntu/lucid/python2.6/dev-dependency-fix

« back to all changes in this revision

Viewing changes to Lib/test/test_complex.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-02-13 12:51:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090213125100-uufgcb9yeqzujpqw
Tags: upstream-2.6.1
ImportĀ upstreamĀ versionĀ 2.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import unittest, os
 
2
from test import test_support
 
3
 
 
4
import warnings
 
5
warnings.filterwarnings(
 
6
    "ignore",
 
7
    category=DeprecationWarning,
 
8
    message=".*complex divmod.*are deprecated"
 
9
)
 
10
 
 
11
from random import random
 
12
from math import atan2
 
13
 
 
14
INF = float("inf")
 
15
NAN = float("nan")
 
16
# These tests ensure that complex math does the right thing
 
17
 
 
18
class ComplexTest(unittest.TestCase):
 
19
 
 
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)
 
25
            else:
 
26
                unittest.TestCase.assertAlmostEqual(self, a.real, b)
 
27
                unittest.TestCase.assertAlmostEqual(self, a.imag, 0.)
 
28
        else:
 
29
            if isinstance(b, complex):
 
30
                unittest.TestCase.assertAlmostEqual(self, a, b.real)
 
31
                unittest.TestCase.assertAlmostEqual(self, 0., b.imag)
 
32
            else:
 
33
                unittest.TestCase.assertAlmostEqual(self, a, b)
 
34
 
 
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
 
38
        if abs(x) > abs(y):
 
39
            x, y = y, x
 
40
        if y == 0:
 
41
            return abs(x) < eps
 
42
        if x == 0:
 
43
            return abs(y) < eps
 
44
        # check that relative difference < eps
 
45
        self.assert_(abs((x-y)/y) < eps)
 
46
 
 
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)
 
51
 
 
52
    def assertIs(self, a, b):
 
53
        self.assert_(a is b)
 
54
 
 
55
    def check_div(self, x, y):
 
56
        """Compute complex z=x*y, and check that z/x==y and z/y==x."""
 
57
        z = x * y
 
58
        if x != 0:
 
59
            q = z / x
 
60
            self.assertClose(q, y)
 
61
            q = z.__div__(x)
 
62
            self.assertClose(q, y)
 
63
            q = z.__truediv__(x)
 
64
            self.assertClose(q, y)
 
65
        if y != 0:
 
66
            q = z / y
 
67
            self.assertClose(q, x)
 
68
            q = z.__div__(y)
 
69
            self.assertClose(q, x)
 
70
            q = z.__truediv__(y)
 
71
            self.assertClose(q, x)
 
72
 
 
73
    def test_div(self):
 
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:
 
78
                self.check_div(x, y)
 
79
 
 
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)
 
84
 
 
85
        # Just for fun.
 
86
        for i in xrange(100):
 
87
            self.check_div(complex(random(), random()),
 
88
                           complex(random(), random()))
 
89
 
 
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)
 
93
 
 
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)
 
97
 
 
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)
 
101
 
 
102
    def test_coerce(self):
 
103
        self.assertRaises(OverflowError, complex.__coerce__, 1+1j, 1L<<10000)
 
104
 
 
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)
 
116
 
 
117
    def test_mod(self):
 
118
        self.assertRaises(ZeroDivisionError, (1+1j).__mod__, 0+0j)
 
119
 
 
120
        a = 3.33+4.43j
 
121
        try:
 
122
            a % 0
 
123
        except ZeroDivisionError:
 
124
            pass
 
125
        else:
 
126
            self.fail("modulo parama can't be 0")
 
127
 
 
128
    def test_divmod(self):
 
129
        self.assertRaises(ZeroDivisionError, divmod, 1+1j, 0+0j)
 
130
 
 
131
    def test_pow(self):
 
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)
 
138
 
 
139
        a = 3.33+4.43j
 
140
        self.assertEqual(a ** 0j, 1)
 
141
        self.assertEqual(a ** 0.+0.j, 1)
 
142
 
 
143
        self.assertEqual(3j ** 0j, 1)
 
144
        self.assertEqual(3j ** 0, 1)
 
145
 
 
146
        try:
 
147
            0j ** a
 
148
        except ZeroDivisionError:
 
149
            pass
 
150
        else:
 
151
            self.fail("should fail 0.0 to negative or complex power")
 
152
 
 
153
        try:
 
154
            0j ** (3-2j)
 
155
        except ZeroDivisionError:
 
156
            pass
 
157
        else:
 
158
            self.fail("should fail 0.0 to negative or complex power")
 
159
 
 
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)
 
164
 
 
165
        self.assertEqual(0.0j ** 0, 1)
 
166
 
 
167
        b = 5.1+2.3j
 
168
        self.assertRaises(ValueError, pow, a, b, 0)
 
169
 
 
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))
 
174
 
 
175
    def test_conjugate(self):
 
176
        self.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j)
 
177
 
 
178
    def test_constructor(self):
 
179
        class OS:
 
180
            def __init__(self, value): self.value = value
 
181
            def __complex__(self): return self.value
 
182
        class NS(object):
 
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))
 
189
 
 
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)
 
223
 
 
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)
 
230
 
 
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.)
 
234
        def split_zeros(x):
 
235
            """Function that produces different results for 0. and -0."""
 
236
            return atan2(x, -1.)
 
237
 
 
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.))
 
242
 
 
243
        c = 3.14 + 1j
 
244
        self.assert_(complex(c) is c)
 
245
        del c
 
246
 
 
247
        self.assertRaises(TypeError, complex, "1", "1")
 
248
        self.assertRaises(TypeError, complex, 1, "1")
 
249
 
 
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)
 
253
 
 
254
        # SF bug 543840:  complex(string) accepts strings with \0
 
255
        # Fixed in 2.3.
 
256
        self.assertRaises(ValueError, complex, '1+1j\0j')
 
257
 
 
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"))
 
278
 
 
279
        class EvilExc(Exception):
 
280
            pass
 
281
 
 
282
        class evilcomplex:
 
283
            def __complex__(self):
 
284
                raise EvilExc
 
285
 
 
286
        self.assertRaises(EvilExc, complex, evilcomplex())
 
287
 
 
288
        class float2:
 
289
            def __init__(self, value):
 
290
                self.value = value
 
291
            def __float__(self):
 
292
                return self.value
 
293
 
 
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))
 
297
 
 
298
        class complex0(complex):
 
299
            """Test usage of __complex__() when inheriting from 'complex'"""
 
300
            def __complex__(self):
 
301
                return 42j
 
302
 
 
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):
 
308
                return self
 
309
 
 
310
        class complex2(complex):
 
311
            """Make sure that __complex__() calls fail if anything other than a
 
312
            complex is returned"""
 
313
            def __complex__(self):
 
314
                return None
 
315
 
 
316
        self.assertAlmostEqual(complex(complex0(1j)), 42j)
 
317
        self.assertAlmostEqual(complex(complex1(1j)), 2j)
 
318
        self.assertRaises(TypeError, complex, complex2(1j))
 
319
 
 
320
    def test_hash(self):
 
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.)))
 
325
 
 
326
    def test_abs(self):
 
327
        nums = [complex(x/3., y/7.) for x in xrange(-9,9) for y in xrange(-9,9)]
 
328
        for num in nums:
 
329
            self.assertAlmostEqual((num.real**2 + num.imag**2)  ** 0.5, abs(num))
 
330
 
 
331
    def test_repr(self):
 
332
        self.assertEqual(repr(1+6j), '(1+6j)')
 
333
        self.assertEqual(repr(1-6j), '(1-6j)')
 
334
 
 
335
        self.assertNotEqual(repr(-(1+0j)), '(-1+-0j)')
 
336
 
 
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)))
 
341
 
 
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)")
 
349
 
 
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")
 
353
 
 
354
    def test_neg(self):
 
355
        self.assertEqual(-(1+6j), -1-6j)
 
356
 
 
357
    def test_file(self):
 
358
        a = 3.33+4.43j
 
359
        b = 5.1+2.3j
 
360
 
 
361
        fo = None
 
362
        try:
 
363
            fo = open(test_support.TESTFN, "wb")
 
364
            print >>fo, a, b
 
365
            fo.close()
 
366
            fo = open(test_support.TESTFN, "rb")
 
367
            self.assertEqual(fo.read(), "%s %s\n" % (a, b))
 
368
        finally:
 
369
            if (fo is not None) and (not fo.closed):
 
370
                fo.close()
 
371
            try:
 
372
                os.remove(test_support.TESTFN)
 
373
            except (OSError, IOError):
 
374
                pass
 
375
 
 
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))
 
383
 
 
384
    if float.__getformat__("double").startswith("IEEE"):
 
385
        def test_plus_minus_0j(self):
 
386
            # test that -0j and 0j literals are not identified
 
387
            z1, z2 = 0j, -0j
 
388
            self.assertEquals(atan2(z1.imag, -1.), atan2(0., -1.))
 
389
            self.assertEquals(atan2(z2.imag, -1.), atan2(-0., -1.))
 
390
 
 
391
def test_main():
 
392
    test_support.run_unittest(ComplexTest)
 
393
 
 
394
if __name__ == "__main__":
 
395
    test_main()