0001 import unittest, os 0002 from test import test_support 0003 0004 import warnings 0005 warnings.filterwarnings( 0006 "ignore", 0007 category=DeprecationWarning, 0008 message=".*complex divmod.*are deprecated" 0009 ) 0010 0011 from random import random 0012 0013 # These tests ensure that complex math does the right thing 0014 0015 class ComplexTest(unittest.TestCase): 0016 0017 def assertAlmostEqual(self, a, b): 0018 if isinstance(a, complex): 0019 if isinstance(b, complex): 0020 unittest.TestCase.assertAlmostEqual(self, a.real, b.real) 0021 unittest.TestCase.assertAlmostEqual(self, a.imag, b.imag) 0022 else: 0023 unittest.TestCase.assertAlmostEqual(self, a.real, b) 0024 unittest.TestCase.assertAlmostEqual(self, a.imag, 0.) 0025 else: 0026 if isinstance(b, complex): 0027 unittest.TestCase.assertAlmostEqual(self, a, b.real) 0028 unittest.TestCase.assertAlmostEqual(self, 0., b.imag) 0029 else: 0030 unittest.TestCase.assertAlmostEqual(self, a, b) 0031 0032 def assertCloseAbs(self, x, y, eps=1e-9): 0033 """Return true iff floats x and y "are close\"""" 0034 # put the one with larger magnitude second 0035 if abs(x) > abs(y): 0036 x, y = y, x 0037 if y == 0: 0038 return abs(x) < eps 0039 if x == 0: 0040 return abs(y) < eps 0041 # check that relative difference < eps 0042 self.assert_(abs((x-y)/y) < eps) 0043 0044 def assertClose(self, x, y, eps=1e-9): 0045 """Return true iff complexes x and y "are close\"""" 0046 self.assertCloseAbs(x.real, y.real, eps) 0047 self.assertCloseAbs(x.imag, y.imag, eps) 0048 0049 def assertIs(self, a, b): 0050 self.assert_(a is b) 0051 0052 def check_div(self, x, y): 0053 """Compute complex z=x*y, and check that z/x==y and z/y==x.""" 0054 z = x * y 0055 if x != 0: 0056 q = z / x 0057 self.assertClose(q, y) 0058 q = z.__div__(x) 0059 self.assertClose(q, y) 0060 q = z.__truediv__(x) 0061 self.assertClose(q, y) 0062 if y != 0: 0063 q = z / y 0064 self.assertClose(q, x) 0065 q = z.__div__(y) 0066 self.assertClose(q, x) 0067 q = z.__truediv__(y) 0068 self.assertClose(q, x) 0069 0070 def test_div(self): 0071 simple_real = [float(i) for i in xrange(-5, 6)] 0072 simple_complex = [complex(x, y) for x in simple_real for y in simple_real] 0073 for x in simple_complex: 0074 for y in simple_complex: 0075 self.check_div(x, y) 0076 0077 # A naive complex division algorithm (such as in 2.0) is very prone to 0078 # nonsense errors for these (overflows and underflows). 0079 self.check_div(complex(1e200, 1e200), 1+0j) 0080 self.check_div(complex(1e-200, 1e-200), 1+0j) 0081 0082 # Just for fun. 0083 for i in xrange(100): 0084 self.check_div(complex(random(), random()), 0085 complex(random(), random())) 0086 0087 self.assertRaises(ZeroDivisionError, complex.__div__, 1+1j, 0+0j) 0088 # FIXME: The following currently crashes on Alpha 0089 # self.assertRaises(OverflowError, pow, 1e200+1j, 1e200+1j) 0090 0091 def test_truediv(self): 0092 self.assertAlmostEqual(complex.__truediv__(2+0j, 1+1j), 1-1j) 0093 self.assertRaises(ZeroDivisionError, complex.__truediv__, 1+1j, 0+0j) 0094 0095 def test_floordiv(self): 0096 self.assertAlmostEqual(complex.__floordiv__(3+0j, 1.5+0j), 2) 0097 self.assertRaises(ZeroDivisionError, complex.__floordiv__, 3+0j, 0+0j) 0098 0099 def test_coerce(self): 0100 self.assertRaises(OverflowError, complex.__coerce__, 1+1j, 1L<<10000) 0101 0102 def test_richcompare(self): 0103 self.assertRaises(OverflowError, complex.__eq__, 1+1j, 1L<<10000) 0104 self.assertEqual(complex.__lt__(1+1j, None), NotImplemented) 0105 self.assertIs(complex.__eq__(1+1j, 1+1j), True) 0106 self.assertIs(complex.__eq__(1+1j, 2+2j), False) 0107 self.assertIs(complex.__ne__(1+1j, 1+1j), False) 0108 self.assertIs(complex.__ne__(1+1j, 2+2j), True) 0109 self.assertRaises(TypeError, complex.__lt__, 1+1j, 2+2j) 0110 self.assertRaises(TypeError, complex.__le__, 1+1j, 2+2j) 0111 self.assertRaises(TypeError, complex.__gt__, 1+1j, 2+2j) 0112 self.assertRaises(TypeError, complex.__ge__, 1+1j, 2+2j) 0113 0114 def test_mod(self): 0115 self.assertRaises(ZeroDivisionError, (1+1j).__mod__, 0+0j) 0116 0117 a = 3.33+4.43j 0118 try: 0119 a % 0 0120 except ZeroDivisionError: 0121 pass 0122 else: 0123 self.fail("modulo parama can't be 0") 0124 0125 def test_divmod(self): 0126 self.assertRaises(ZeroDivisionError, divmod, 1+1j, 0+0j) 0127 0128 def test_pow(self): 0129 self.assertAlmostEqual(pow(1+1j, 0+0j), 1.0) 0130 self.assertAlmostEqual(pow(0+0j, 2+0j), 0.0) 0131 self.assertRaises(ZeroDivisionError, pow, 0+0j, 1j) 0132 self.assertAlmostEqual(pow(1j, -1), 1/1j) 0133 self.assertAlmostEqual(pow(1j, 200), 1) 0134 self.assertRaises(ValueError, pow, 1+1j, 1+1j, 1+1j) 0135 0136 a = 3.33+4.43j 0137 self.assertEqual(a ** 0j, 1) 0138 self.assertEqual(a ** 0.+0.j, 1) 0139 0140 self.assertEqual(3j ** 0j, 1) 0141 self.assertEqual(3j ** 0, 1) 0142 0143 try: 0144 0j ** a 0145 except ZeroDivisionError: 0146 pass 0147 else: 0148 self.fail("should fail 0.0 to negative or complex power") 0149 0150 try: 0151 0j ** (3-2j) 0152 except ZeroDivisionError: 0153 pass 0154 else: 0155 self.fail("should fail 0.0 to negative or complex power") 0156 0157 # The following is used to exercise certain code paths 0158 self.assertEqual(a ** 105, a ** 105) 0159 self.assertEqual(a ** -105, a ** -105) 0160 self.assertEqual(a ** -30, a ** -30) 0161 0162 self.assertEqual(0.0j ** 0, 1) 0163 0164 b = 5.1+2.3j 0165 self.assertRaises(ValueError, pow, a, b, 0) 0166 0167 def test_boolcontext(self): 0168 for i in xrange(100): 0169 self.assert_(complex(random() + 1e-6, random() + 1e-6)) 0170 self.assert_(not complex(0.0, 0.0)) 0171 0172 def test_conjugate(self): 0173 self.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j) 0174 0175 def test_constructor(self): 0176 class OS: 0177 def __init__(self, value): self.value = value 0178 def __complex__(self): return self.value 0179 class NS(object): 0180 def __init__(self, value): self.value = value 0181 def __complex__(self): return self.value 0182 self.assertEqual(complex(OS(1+10j)), 1+10j) 0183 self.assertEqual(complex(NS(1+10j)), 1+10j) 0184 self.assertRaises(TypeError, complex, OS(None)) 0185 self.assertRaises(TypeError, complex, NS(None)) 0186 0187 self.assertAlmostEqual(complex("1+10j"), 1+10j) 0188 self.assertAlmostEqual(complex(10), 10+0j) 0189 self.assertAlmostEqual(complex(10.0), 10+0j) 0190 self.assertAlmostEqual(complex(10L), 10+0j) 0191 self.assertAlmostEqual(complex(10+0j), 10+0j) 0192 self.assertAlmostEqual(complex(1,10), 1+10j) 0193 self.assertAlmostEqual(complex(1,10L), 1+10j) 0194 self.assertAlmostEqual(complex(1,10.0), 1+10j) 0195 self.assertAlmostEqual(complex(1L,10), 1+10j) 0196 self.assertAlmostEqual(complex(1L,10L), 1+10j) 0197 self.assertAlmostEqual(complex(1L,10.0), 1+10j) 0198 self.assertAlmostEqual(complex(1.0,10), 1+10j) 0199 self.assertAlmostEqual(complex(1.0,10L), 1+10j) 0200 self.assertAlmostEqual(complex(1.0,10.0), 1+10j) 0201 self.assertAlmostEqual(complex(3.14+0j), 3.14+0j) 0202 self.assertAlmostEqual(complex(3.14), 3.14+0j) 0203 self.assertAlmostEqual(complex(314), 314.0+0j) 0204 self.assertAlmostEqual(complex(314L), 314.0+0j) 0205 self.assertAlmostEqual(complex(3.14+0j, 0j), 3.14+0j) 0206 self.assertAlmostEqual(complex(3.14, 0.0), 3.14+0j) 0207 self.assertAlmostEqual(complex(314, 0), 314.0+0j) 0208 self.assertAlmostEqual(complex(314L, 0L), 314.0+0j) 0209 self.assertAlmostEqual(complex(0j, 3.14j), -3.14+0j) 0210 self.assertAlmostEqual(complex(0.0, 3.14j), -3.14+0j) 0211 self.assertAlmostEqual(complex(0j, 3.14), 3.14j) 0212 self.assertAlmostEqual(complex(0.0, 3.14), 3.14j) 0213 self.assertAlmostEqual(complex("1"), 1+0j) 0214 self.assertAlmostEqual(complex("1j"), 1j) 0215 self.assertAlmostEqual(complex(), 0) 0216 self.assertAlmostEqual(complex("-1"), -1) 0217 self.assertAlmostEqual(complex("+1"), +1) 0218 0219 class complex2(complex): pass 0220 self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j) 0221 self.assertAlmostEqual(complex(real=17, imag=23), 17+23j) 0222 self.assertAlmostEqual(complex(real=17+23j), 17+23j) 0223 self.assertAlmostEqual(complex(real=17+23j, imag=23), 17+46j) 0224 self.assertAlmostEqual(complex(real=1+2j, imag=3+4j), -3+5j) 0225 0226 c = 3.14 + 1j 0227 self.assert_(complex(c) is c) 0228 del c 0229 0230 self.assertRaises(TypeError, complex, "1", "1") 0231 self.assertRaises(TypeError, complex, 1, "1") 0232 0233 self.assertEqual(complex(" 3.14+J "), 3.14+1j) 0234 if test_support.have_unicode: 0235 self.assertEqual(complex(unicode(" 3.14+J ")), 3.14+1j) 0236 0237 # SF bug 543840: complex(string) accepts strings with \0 0238 # Fixed in 2.3. 0239 self.assertRaises(ValueError, complex, '1+1j\0j') 0240 0241 self.assertRaises(TypeError, int, 5+3j) 0242 self.assertRaises(TypeError, long, 5+3j) 0243 self.assertRaises(TypeError, float, 5+3j) 0244 self.assertRaises(ValueError, complex, "") 0245 self.assertRaises(TypeError, complex, None) 0246 self.assertRaises(ValueError, complex, "\0") 0247 self.assertRaises(TypeError, complex, "1", "2") 0248 self.assertRaises(TypeError, complex, "1", 42) 0249 self.assertRaises(TypeError, complex, 1, "2") 0250 self.assertRaises(ValueError, complex, "1+") 0251 self.assertRaises(ValueError, complex, "1+1j+1j") 0252 self.assertRaises(ValueError, complex, "--") 0253 if test_support.have_unicode: 0254 self.assertRaises(ValueError, complex, unicode("1"*500)) 0255 self.assertRaises(ValueError, complex, unicode("x")) 0256 0257 class EvilExc(Exception): 0258 pass 0259 0260 class evilcomplex: 0261 def __complex__(self): 0262 raise EvilExc 0263 0264 self.assertRaises(EvilExc, complex, evilcomplex()) 0265 0266 class float2: 0267 def __init__(self, value): 0268 self.value = value 0269 def __float__(self): 0270 return self.value 0271 0272 self.assertAlmostEqual(complex(float2(42.)), 42) 0273 self.assertAlmostEqual(complex(real=float2(17.), imag=float2(23.)), 17+23j) 0274 self.assertRaises(TypeError, complex, float2(None)) 0275 0276 def test_hash(self): 0277 for x in xrange(-30, 30): 0278 self.assertEqual(hash(x), hash(complex(x, 0))) 0279 x /= 3.0 # now check against floating point 0280 self.assertEqual(hash(x), hash(complex(x, 0.))) 0281 0282 def test_abs(self): 0283 nums = [complex(x/3., y/7.) for x in xrange(-9,9) for y in xrange(-9,9)] 0284 for num in nums: 0285 self.assertAlmostEqual((num.real**2 + num.imag**2) ** 0.5, abs(num)) 0286 0287 def test_repr(self): 0288 self.assertEqual(repr(1+6j), '(1+6j)') 0289 self.assertEqual(repr(1-6j), '(1-6j)') 0290 0291 def test_neg(self): 0292 self.assertEqual(-(1+6j), -1-6j) 0293 0294 def test_file(self): 0295 a = 3.33+4.43j 0296 b = 5.1+2.3j 0297 0298 fo = None 0299 try: 0300 fo = open(test_support.TESTFN, "wb") 0301 print >>fo, a, b 0302 fo.close() 0303 fo = open(test_support.TESTFN, "rb") 0304 self.assertEqual(fo.read(), "%s %s\n" % (a, b)) 0305 finally: 0306 if (fo is not None) and (not fo.closed): 0307 fo.close() 0308 try: 0309 os.remove(test_support.TESTFN) 0310 except (OSError, IOError): 0311 pass 0312 0313 def test_main(): 0314 test_support.run_unittest(ComplexTest) 0315 0316 if __name__ == "__main__": 0317 test_main() 0318
Generated by PyXR 0.9.4