mpmath 0.2__zip → 0.4__zip

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,515 +0,0 @@
1
- from lib import *
2
- from decimal import Decimal
3
-
4
- class mpnumeric(object):
5
- """Base class for mpf and mpc. Calling mpnumeric(x) returns an mpf
6
- if x can be converted to an mpf (if it is a float, int, mpf, ...),
7
- and an mpc if x is complex."""
8
- def __new__(cls, val):
9
- if isinstance(val, cls):
10
- return val
11
- if isinstance(val, complex):
12
- return mpc(val)
13
- return mpf(val)
14
-
15
- class context(type):
16
- """Metaclass for mpf and mpc. Holds global working precision."""
17
- _prec = 53
18
- _dps = 15
19
- _rounding = ROUND_HALF_EVEN
20
- def _setprec(self, n):
21
- self._prec = max(1, int(n))
22
- self._dps = max(1, int(round(int(n)/LOG2_10)-1))
23
- prec = property(lambda self: self._prec, _setprec)
24
- def _setdps(self, n):
25
- self._prec = max(1, int(round((int(n)+1)*LOG2_10)))
26
- self._dps = max(1, int(n))
27
- dps = property(lambda self: self._dps, _setdps)
28
-
29
- def round_up(self): self._rounding = ROUND_UP
30
- def round_down(self): self._rounding = ROUND_DOWN
31
- def round_floor(self): self._rounding = ROUND_FLOOR
32
- def round_ceiling(self): self._rounding = ROUND_CEILING
33
- def round_half_down(self): self._rounding = ROUND_HALF_DOWN
34
- def round_half_up(self): self._rounding = ROUND_HALF_UP
35
- def round_half_even(self): self._rounding = ROUND_HALF_EVEN
36
-
37
- round_default = round_half_even
38
-
39
-
40
- inttypes = (int, long)
41
-
42
- def _convert(x):
43
- """Convet x to mpf data"""
44
- if isinstance(x, float):
45
- return float_from_pyfloat(x, mpf._prec, mpf._rounding)
46
- if isinstance(x, inttypes):
47
- return float_from_int(x, mpf._prec, mpf._rounding)
48
- if isinstance(x, (Decimal, str)):
49
- return decimal_to_binary(x, mpf._prec, mpf._rounding)
50
- raise TypeError("cannot create mpf from " + repr(x))
51
-
52
-
53
- class mpf(mpnumeric):
54
-
55
- __metaclass__ = context
56
-
57
- def __new__(cls, val=fzero):
58
- if isinstance(val, mpf):
59
- return _make_mpf(normalize(val.val[0], val.val[1], \
60
- cls._prec, cls._rounding))
61
- elif isinstance(val, tuple):
62
- return _make_mpf(normalize(val[0], val[1], cls._prec, \
63
- cls._rounding))
64
- else:
65
- return _make_mpf(_convert(val))
66
-
67
- man = property(lambda self: self.val[0])
68
- exp = property(lambda self: self.val[1])
69
- bc = property(lambda self: self.val[2])
70
-
71
- def __repr__(s):
72
- st = "mpf('%s')"
73
- return st % binary_to_decimal(s.val, mpf._dps+2)
74
-
75
- def __str__(s):
76
- return binary_to_decimal(s.val, mpf._dps)
77
-
78
- def __hash__(s):
79
- try:
80
- # Try to be compatible with hash values for floats and ints
81
- return hash(float(s))
82
- except OverflowError:
83
- # We must unfortunately sacrifice compatibility with ints here. We
84
- # could do hash(man << exp) when the exponent is positive, but
85
- # this would cause unreasonable inefficiency for large numbers.
86
- return hash(self.val)
87
-
88
- def __int__(s):
89
- return float_to_int(s.val)
90
-
91
- def __float__(s):
92
- return float_to_pyfloat(s.val)
93
-
94
- def __complex__(s):
95
- return float(s) + 0j
96
-
97
- def __eq__(s, t):
98
- if not isinstance(t, mpf):
99
- if isinstance(t, complex_types):
100
- return mpc(s) == t
101
- if isinstance(t, str):
102
- return False
103
- try:
104
- t = mpf(t)
105
- except Exception:
106
- return False
107
- return s.val == t.val
108
-
109
- def __ne__(s, t):
110
- if not isinstance(t, mpf):
111
- if isinstance(t, complex_types):
112
- return mpc(s) != t
113
- if isinstance(t, str):
114
- return True
115
- try:
116
- t = mpf(t)
117
- except Exception:
118
- return True
119
- t = mpf(t)
120
- return s.val != t.val
121
-
122
- def __cmp__(s, t):
123
- if not isinstance(t, mpf):
124
- t = mpf(t)
125
- return fcmp(s.val, t.val)
126
-
127
- def __abs__(s):
128
- return _make_mpf(fabs(s.val, mpf._prec, mpf._rounding))
129
-
130
- def __pos__(s):
131
- return mpf(s)
132
-
133
- def __neg__(s):
134
- return _make_mpf(fneg(s.val, mpf._prec, mpf._rounding))
135
-
136
- def __add__(s, t):
137
- if not isinstance(t, mpf):
138
- if isinstance(t, inttypes):
139
- return _make_mpf(fadd(s.val, (t, 0, bitcount(t)), mpf._prec, mpf._rounding))
140
- if isinstance(t, complex_types):
141
- return mpc(s) + t
142
- t = mpf(t)
143
- return _make_mpf(fadd(s.val, t.val, mpf._prec, mpf._rounding))
144
-
145
- __radd__ = __add__
146
-
147
- def __sub__(s, t):
148
- if not isinstance(t, mpf):
149
- if isinstance(t, inttypes):
150
- return _make_mpf(fsub(s.val, (t, 0, bitcount(t)), mpf._prec, mpf._rounding))
151
- if isinstance(t, complex_types):
152
- return mpc(s) - t
153
- t = mpf(t)
154
- return _make_mpf(fsub(s.val, t.val, mpf._prec, mpf._rounding))
155
-
156
- def __rsub__(s, t):
157
- if not isinstance(t, mpf):
158
- if isinstance(t, inttypes):
159
- return _make_mpf(fsub((t, 0, bitcount(t)), s.val, mpf._prec, mpf._rounding))
160
- if isinstance(t, complex_types):
161
- return t - mpc(s)
162
- t = mpf(t)
163
- return _make_mpf(fsub(t.val, s.val, mpf._prec, mpf._rounding))
164
-
165
- def __mul__(s, t):
166
- if not isinstance(t, mpf):
167
- if isinstance(t, inttypes):
168
- return _make_mpf(normalize(s.val[0]*t, s.val[1], mpf._prec, mpf._rounding))
169
- if isinstance(t, complex_types):
170
- return mpc(s) * t
171
- t = mpf(t)
172
- return _make_mpf(fmul(s.val, t.val, mpf._prec, mpf._rounding))
173
-
174
- __rmul__ = __mul__
175
-
176
- def __div__(s, t):
177
- if not isinstance(t, mpf):
178
- if isinstance(t, inttypes):
179
- return _make_mpf(fdiv(s.val, (t, 0, bitcount(t)), mpf._prec, mpf._rounding))
180
- if isinstance(t, complex_types):
181
- return mpc(s) / t
182
- t = mpf(t)
183
- return _make_mpf(fdiv(s.val, t.val, mpf._prec, mpf._rounding))
184
-
185
- def __rdiv__(s, t):
186
- if not isinstance(t, mpf):
187
- if isinstance(t, inttypes):
188
- return _make_mpf(fdiv((t, 0, bitcount(t)), s.val, mpf._prec, mpf._rounding))
189
- if isinstance(t, complex_types):
190
- return t / mpc(s)
191
- t = mpf(t)
192
- return _make_mpf(fdiv(t.val, s.val, mpf._prec, mpf._rounding))
193
-
194
- def __pow__(s, t):
195
- if isinstance(t, inttypes):
196
- return _make_mpf(fpow(s.val, t, mpf._prec, mpf._rounding))
197
- if not isinstance(t, mpf):
198
- if isinstance(t, complex_types):
199
- return power(s, t)
200
- t = mpf(t)
201
- if t == 0.5:
202
- return sqrt(s)
203
- intt = int(t)
204
- if t == intt:
205
- return _make_mpf(fpow(s.val, intt, mpf._prec, mpf._rounding))
206
- return power(s, t)
207
-
208
- def sqrt(s):
209
- return sqrt(s)
210
-
211
- def ae(s, t, rel_eps=None, abs_eps=None):
212
- """
213
- Determine whether the difference between s and t is smaller
214
- than a given epsilon ("ae" is short for "almost equal").
215
-
216
- Both a maximum relative difference and a maximum difference
217
- ('epsilons') may be specified. The absolute difference is
218
- defined as |s-t| and the relative difference is defined
219
- as |s-t|/max(|s|, |t|).
220
-
221
- If only one epsilon is given, both are set to the same value.
222
- If none is given, both epsilons are set to 2**(-prec+m) where
223
- prec is the current working precision and m is a small integer.
224
- """
225
- if not isinstance(t, mpf):
226
- t = mpf(t)
227
- if abs_eps is None and rel_eps is None:
228
- rel_eps = abs_eps = _make_mpf((1, -mpf._prec+4, 1))
229
- if abs_eps is None:
230
- abs_eps = rel_eps
231
- elif rel_eps is None:
232
- rel_eps = abs_eps
233
- diff = abs(s-t)
234
- if diff <= abs_eps:
235
- return True
236
- abss = abs(s)
237
- abst = abs(t)
238
- if abss < abst:
239
- err = diff/abst
240
- else:
241
- err = diff/abss
242
- return err <= rel_eps
243
-
244
- def almost_zero(s, prec):
245
- """Quick check if |s| < 2**-prec. May return a false negative
246
- if s is very close to the threshold."""
247
- return s.bc + s.exp < prec
248
-
249
-
250
-
251
-
252
- def _make_mpf(tpl, construct=object.__new__, cls=mpf):
253
- a = construct(cls)
254
- a.val = tpl
255
- return a
256
-
257
-
258
- class constant(mpf):
259
-
260
- def __new__(cls, func):
261
- a = object.__new__(cls)
262
- a.func = func
263
- return a
264
-
265
- @property
266
- def val(self):
267
- return self.func(mpf._prec, mpf._rounding)
268
-
269
-
270
- pi = constant(fpi)
271
- e = constant(lambda p, r: fexp(fone, p, r))
272
- cgamma = constant(fgamma)
273
- clog2 = constant(flog2)
274
- clog10 = constant(flog10)
275
-
276
-
277
- def hypot(x, y):
278
- x = mpf(x)
279
- y = mpf(y)
280
- return mpf(fhypot(x.val, y.val, mpf._prec, mpf._rounding))
281
-
282
-
283
- class mpc(mpnumeric):
284
-
285
- def __new__(cls, real=0, imag=0):
286
- s = object.__new__(cls)
287
- if isinstance(real, (complex, mpc)):
288
- real, imag = real.real, real.imag
289
- s.real = mpf(real)
290
- s.imag = mpf(imag)
291
- return s
292
-
293
- def __repr__(s):
294
- r = repr(s.real)[4:-1]
295
- i = repr(s.imag)[4:-1]
296
- return "mpc(real=%s, imag=%s)" % (r, i)
297
-
298
- def __str__(s):
299
- return "(%s + %sj)" % (s.real, s.imag)
300
-
301
- def __complex__(s):
302
- return complex(float(s.real), float(s.imag))
303
-
304
- def __pos__(s):
305
- return mpc(s.real, s.imag)
306
-
307
- def __abs__(s):
308
- return hypot(s.real, s.imag)
309
-
310
- def __eq__(s, t):
311
- if not isinstance(t, mpc):
312
- if isinstance(t, str):
313
- return False
314
- t = mpc(t)
315
- return s.real == t.real and s.imag == t.imag
316
-
317
- def _compare(*args):
318
- raise TypeError("no ordering relation is defined for complex numbers")
319
-
320
- __gt__ = _compare
321
- __le__ = _compare
322
- __gt__ = _compare
323
- __ge__ = _compare
324
-
325
- def __nonzero__(s):
326
- return s.real != 0 or s.imag != 0
327
-
328
- def conjugate(s):
329
- return mpc(s.real, -s.imag)
330
-
331
- def __add__(s, t):
332
- if not isinstance(t, mpc):
333
- t = mpc(t)
334
- return mpc(s.real+t.real, s.imag+t.imag)
335
-
336
- __radd__ = __add__
337
-
338
- def __neg__(s):
339
- return mpc(-s.real, -s.imag)
340
-
341
- def __sub__(s, t):
342
- if not isinstance(t, mpc):
343
- t = mpc(t)
344
- return mpc(s.real-t.real, s.imag-t.imag)
345
-
346
- def __rsub__(s, t):
347
- return (-s) + t
348
-
349
- def __mul__(s, t):
350
- if not isinstance(t, mpc):
351
- t = mpc(t)
352
- a = s.real; b = s.imag; c = t.real; d = t.imag
353
- if b == d == 0:
354
- return mpc(a*c, 0)
355
- else:
356
- return mpc(a*c-b*d, a*d+b*c)
357
-
358
- __rmul__ = __mul__
359
-
360
- def __div__(s, t):
361
- if not isinstance(t, mpc):
362
- t = mpc(t)
363
- a = s.real; b = s.imag; c = t.real; d = t.imag
364
- mag = c*c + d*d
365
- return mpc((a*c+b*d)/mag, (b*c-a*d)/mag)
366
-
367
- def __rdiv__(s, t):
368
- return mpc(t) / s
369
-
370
- def __pow__(s, n):
371
- if n == 0: return mpc(1)
372
- if n == 1: return +s
373
- if n == -1: return 1/s
374
- if n == 2: return s*s
375
- if isinstance(n, (int, long)) and n > 0:
376
- # TODO: should increase working precision here
377
- w = mpc(1)
378
- while n:
379
- if n & 1:
380
- w = w*s
381
- n -= 1
382
- s = s*s
383
- n //= 2
384
- return w
385
- if n == 0.5:
386
- return sqrt(s)
387
- return power(s, n)
388
-
389
- # TODO: refactor and merge with mpf.ae
390
- def ae(s, t, rel_eps=None, abs_eps=None):
391
- if not isinstance(t, mpc):
392
- t = mpc(t)
393
- if abs_eps is None and rel_eps is None:
394
- abs_eps = rel_eps = _make_mpf((1, -mpf._prec+4, 1))
395
- if abs_eps is None:
396
- abs_eps = rel_eps
397
- elif rel_eps is None:
398
- rel_eps = abs_eps
399
- diff = abs(s-t)
400
- if diff <= abs_eps:
401
- return True
402
- abss = abs(s)
403
- abst = abs(t)
404
- if abss < abst:
405
- err = diff/abst
406
- else:
407
- err = diff/abss
408
- return err <= rel_eps
409
-
410
-
411
-
412
- complex_types = (complex, mpc)
413
-
414
-
415
- def _make_mpc(tpl, construct=object.__new__, cls=mpc):
416
- a = construct(cls)
417
- a.real, a.imag = map(_make_mpf, tpl)
418
- return a
419
-
420
- j = mpc(0,1)
421
-
422
-
423
- def sqrt(x):
424
- x = mpnumeric(x)
425
- if isinstance(x, mpf) and x >= 0:
426
- return _make_mpf(fsqrt(x.val, mpf._prec, mpf._rounding))
427
- x = mpc(x)
428
- return _make_mpc(fcsqrt(x.real.val, x.imag.val, mpf._prec, mpf._rounding))
429
-
430
- def exp(x):
431
- x = mpnumeric(x)
432
- if isinstance(x, mpf):
433
- return _make_mpf(fexp(x.val, mpf._prec, mpf._rounding))
434
- else:
435
- return _make_mpc(fcexp(x.real.val, x.imag.val, mpf._prec, mpf._rounding))
436
-
437
- def log(x, base=None):
438
- if base is not None:
439
- mpf.prec += 3
440
- a = log(x) / log(base)
441
- mpf.prec -= 3
442
- return +a
443
- x = mpnumeric(x)
444
- if not x:
445
- raise ValueError, "logarithm of 0"
446
- if isinstance(x, mpf) and x > 0:
447
- return _make_mpf(flog(x.val, mpf._prec, mpf._rounding))
448
- else:
449
- x = mpc(x)
450
- mpf._prec += 3
451
- mag = abs(x)
452
- phase = atan2(x.imag, x.real)
453
- mpf._prec -= 3
454
- return mpc(log(mag), phase)
455
-
456
- def power(x, y):
457
- # TODO: accurate estimate for extra precision needed
458
- mpf._prec += 10
459
- t = exp(y * log(x))
460
- mpf._prec -= 10
461
- return +t
462
-
463
- def cos(x):
464
- x = mpnumeric(x)
465
- if isinstance(x, mpf):
466
- return _make_mpf(fcos(x.val, mpf._prec, mpf._rounding))
467
- else:
468
- return _make_mpc(fccos(x.real.val, x.imag.val, mpf._prec, mpf._rounding))
469
-
470
- def sin(x):
471
- x = mpnumeric(x)
472
- if isinstance(x, mpf):
473
- return _make_mpf(fsin(x.val, mpf._prec, mpf._rounding))
474
- else:
475
- return _make_mpc(fcsin(x.real.val, x.imag.val, mpf._prec, mpf._rounding))
476
-
477
- def tan(x):
478
- x = mpnumeric(x)
479
- if isinstance(x, mpf):
480
- return _make_mpf(ftan(x.val, mpf._prec, mpf._rounding))
481
- return sin(x) / cos(x)
482
-
483
- def atan(x):
484
- x = mpnumeric(x)
485
- if isinstance(x, mpf):
486
- return _make_mpf(fatan(x.val, mpf._prec, mpf._rounding))
487
- raise NotImplementedError
488
-
489
- def atan2(y,x):
490
- """atan2(y, x) has the same magnitude as atan(y/x) but
491
- accounts for the signs of y and x"""
492
- x = mpf(x)
493
- y = mpf(y)
494
- if y < 0:
495
- return -atan2(-y, x)
496
- if not x and not y:
497
- return mpf(0)
498
- if y > 0 and x == 0:
499
- mpf._prec += 2
500
- t = pi/2
501
- mpf._prec -= 2
502
- return t
503
- mpf._prec += 2
504
- if x > 0:
505
- a = atan(y/x)
506
- else:
507
- a = pi - atan(-y/x)
508
- mpf._prec -= 2
509
- return +a
510
-
511
-
512
-
513
- __all__ = ["mpnumeric", "mpf", "mpc", "pi", "e", "cgamma", "clog2", "clog10", "j",
514
- "sqrt", "hypot", "exp", "log", "cos", "sin", "tan", "atan", "atan2", "power"]
515
-
File without changes