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.
@@ -2,10 +2,10 @@ from distutils.core import setup
2
2
 
3
3
  setup(name='mpmath',
4
4
  description = 'Python library for arbitrary-precision floating-point arithmetic',
5
- version='0.2',
5
+ version='0.4',
6
6
  url='http://mpmath.googlecode.com',
7
7
  author='Fredrik Johansson',
8
8
  author_email='fredrik.johansson@gmail.com',
9
9
  license = 'BSD',
10
- packages=['mpmath'],
10
+ packages=['mpmath', 'mpmath/lib'],
11
11
  )
@@ -0,0 +1,139 @@
1
+ from mpmath import *
2
+ from mpmath.lib import *
3
+ from decimal import getcontext, Decimal
4
+ import dmath
5
+ from random import seed, random, randint
6
+
7
+ def getrandom(type):
8
+ if type == 'mpf':
9
+ return mpf(random() * 2.0**randint(-10, 10)) ** 0.5
10
+ if type == 'mpfval':
11
+ return (mpf(random() * 2.0**randint(-10, 10)) ** 0.5).val
12
+ if type == 'Decimal':
13
+ return Decimal(repr(random() * 2.0**randint(-10, 10))).sqrt()
14
+ raise TypeError
15
+
16
+ def rndnums(type, N):
17
+ seed(1234)
18
+ xs = [getrandom(type) for i in xrange(N)]
19
+ ys = xs[::-1]
20
+ xys = zip(xs, ys)
21
+ return xs, ys, xys
22
+
23
+ def setprec(type, prec):
24
+ if type == 'Decimal':
25
+ getcontext().prec = prec
26
+ else:
27
+ mpf.dps = prec
28
+ # change prec value to bits for mpfval use
29
+ prec = mpf.prec
30
+ return prec
31
+
32
+ testcode = \
33
+ """
34
+ def testit(prec, N):
35
+ from time import clock
36
+ RF = ROUND_HALF_EVEN
37
+ prec = setprec('TYPE', prec)
38
+ xs, ys, xys = rndnums('TYPE', N)
39
+ t = 1e100
40
+ for i in range(3):
41
+ t1 = clock()
42
+ for x, y in xys:
43
+ OP
44
+ t2 = clock()
45
+ t = min(t, t2-t1)
46
+ return t
47
+ """
48
+
49
+ tests = []
50
+ atests = [
51
+ ('Convert to integer (int(x))', 'int(x)', 'int(x)', 'to_int(x)'),
52
+ ('Convert to string (str(x))', 'str(x)', 'str(x)', 'to_str(x, int(prec/3.321))'),
53
+ ('Convert to float (float(x))', 'float(x)', 'float(x)', 'to_float(x)'),
54
+ ('Equality (x==y)', 'x==y', 'x==y', 'feq(x, y)'),
55
+ ('Comparison (x<y)', 'x<y', 'x<y', 'fcmp(x, y) < 0'),
56
+ ('Addition (x+y)', 'x+y', 'x+y', 'fadd(x, y, prec, RF)'),
57
+ ('Subtraction (x-y)', 'x+y', 'x+y', 'fsub(x, y, prec, RF)'),
58
+ ('Multiplication (x*y)', 'x*y', 'x*y', 'fmul(x, y, prec, RF)'),
59
+ ('Division (x/y)', 'x/y', 'x/y', 'fdiv(x, y, prec, RF)'),
60
+ ('Square root (x^0.5)', 'x.sqrt()', 'sqrt(x)', 'fsqrt(x, prec, RF)'),
61
+ ('Integer power (x^42)', 'x**42', 'x**42', 'fpow(x, 42, prec, RF)'),
62
+ ('Exponential function (exp(x))', 'dmath.exp(x)', 'exp(x)', 'fexp(x, prec, RF)'),
63
+ ('Natural logarithm (log(x))', 'dmath.log(x+1)', 'log(x)', 'flog(x, prec, RF)'),
64
+ ('Sine (sin(x))', 'dmath.sin(x)', 'sin(x)', 'fsin(x, prec, RF)'),
65
+ ('Tangent (tan(x))', 'dmath.tan(x)', 'tan(x)', 'ftan(x, prec, RF)'),
66
+ ('Inverse tangent(atan(x))', 'dmath.atan(x)', 'atan(x)', 'fatan(x, prec, RF)'),
67
+ ('Hyperbolic cosine (cosh(x))', 'dmath.cosh(x)', 'cosh(x)', 'fcosh(x, prec, RF)')
68
+ ]
69
+
70
+ slow = ["exp", "log", "sin", "tan", "cos"]
71
+
72
+ for op in atests:
73
+ cases = [op[0]]
74
+ if op[1]:
75
+ exec testcode.replace("OP", op[1]).replace("TYPE", "Decimal")
76
+ cases += [testit]
77
+ else:
78
+ cases += [None]
79
+ exec testcode.replace("OP", op[2]).replace("TYPE", "mpf")
80
+ cases += [testit]
81
+ exec testcode.replace("OP", op[3]).replace("TYPE", "mpfval")
82
+ cases += [testit]
83
+ tests.append(cases)
84
+
85
+ def rd(x):
86
+ if x > 100000: return int(x // 10000) * 10000
87
+ if x > 10000: return int(x // 1000) * 1000
88
+ if x > 1000: return int(x // 100) * 100
89
+ if x > 100: return int(x // 10) * 10
90
+ return int(x)
91
+
92
+ def runtests():
93
+ results = []
94
+ for test in tests:
95
+ name, dectest, mpftest, mpfvaltest = test
96
+ if any(s in name for s in slow):
97
+ N = 1
98
+ precs = [15, 30, 100, 300]
99
+ else:
100
+ N = 10
101
+ precs = [15, 30, 100, 300, 1000]
102
+ header_name = "*" + name + "*"
103
+ rows = []
104
+ for prec in precs:
105
+ print name, prec
106
+ if dectest is None:
107
+ t1 = 1e1000-1e1000
108
+ else:
109
+ t1 = dectest(prec, N)
110
+ t2 = mpftest(prec, N)
111
+ t3 = mpfvaltest(prec, N)
112
+ s = []
113
+ s += ["%i" % prec]
114
+ s += [str(rd(N/t1))]
115
+ s += [str(rd(N/t2)) + (" (%.1fx)" % (t1/t2))]
116
+ s += [str(rd(N/t3)) + (" (%.1fx)" % (t1/t3))]
117
+ rows.append(s)
118
+ results.append((header_name, rows))
119
+ return results
120
+
121
+ import gc
122
+ gc.disable()
123
+ results1 = runtests()
124
+ import psyco
125
+ psyco.full()
126
+ results2 = runtests()
127
+
128
+ import sys
129
+ sys.stdout = open("results.txt", "w")
130
+
131
+ for r1, r2 in zip(results1, results2):
132
+ name = r1[0]
133
+ print name
134
+ print "|| *digits* || *Decimal* || *mpf* || *raw mpf* || *Decimal+psyco* || *mpf+psyco* || *raw mpf+psyco* ||"
135
+ for a, b in zip(r1[1], r2[1]):
136
+ cols = a + b[1:]
137
+ print "|| " + (" || ".join(cols)) + " ||"
138
+ print
139
+
@@ -0,0 +1,5 @@
1
+ #!C:\Python25\python.exe
2
+
3
+ #from _findpy import py
4
+ import py
5
+ py.test.cmdline.main()
@@ -0,0 +1,110 @@
1
+ """
2
+ Test bit-level integer operations
3
+ """
4
+
5
+ from mpmath.lib import *
6
+
7
+ def test_bitcount():
8
+ assert bitcount(0) == 0
9
+ assert bitcount(1) == 1
10
+ assert bitcount(7) == 3
11
+ assert bitcount(8) == 4
12
+ assert bitcount(2**100) == 101
13
+ assert bitcount(2**100-1) == 100
14
+ assert bitcount(-(2**100)) == 101
15
+ assert bitcount(-(2**100-1)) == 100
16
+
17
+ def test_trailing_zeros():
18
+ assert trailing_zeros(0) == 0
19
+ assert trailing_zeros(1) == 0
20
+ assert trailing_zeros(2) == 1
21
+ assert trailing_zeros(7) == 0
22
+ assert trailing_zeros(8) == 3
23
+ assert trailing_zeros(2**100) == 100
24
+ assert trailing_zeros(2**100-1) == 0
25
+
26
+ def test_round_down():
27
+ assert normalize(0, -4, 4, ROUND_DOWN)[:2] == (0, 0)
28
+ assert normalize(0xf0, -4, 4, ROUND_DOWN)[:2] == (15, 0)
29
+ assert normalize(0xf1, -4, 4, ROUND_DOWN)[:2] == (15, 0)
30
+ assert normalize(0xff, -4, 4, ROUND_DOWN)[:2] == (15, 0)
31
+ assert normalize(-0xf0, -4, 4, ROUND_DOWN)[:2] == (-15, 0)
32
+ assert normalize(-0xf1, -4, 4, ROUND_DOWN)[:2] == (-15, 0)
33
+ assert normalize(-0xff, -4, 4, ROUND_DOWN)[:2] == (-15, 0)
34
+
35
+ def test_round_up():
36
+ assert normalize(0, -4, 4, ROUND_UP)[:2] == (0, 0)
37
+ assert normalize(0xf0, -4, 4, ROUND_UP)[:2] == (15, 0)
38
+ assert normalize(0xf1, -4, 4, ROUND_UP)[:2] == (1, 4)
39
+ assert normalize(0xff, -4, 4, ROUND_UP)[:2] == (1, 4)
40
+ assert normalize(-0xf0, -4, 4, ROUND_UP)[:2] == (-15, 0)
41
+ assert normalize(-0xf1, -4, 4, ROUND_UP)[:2] == (-1, 4)
42
+ assert normalize(-0xff, -4, 4, ROUND_UP)[:2] == (-1, 4)
43
+
44
+ def test_round_floor():
45
+ assert normalize(0, -4, 4, ROUND_FLOOR)[:2] == (0, 0)
46
+ assert normalize(0xf0, -4, 4, ROUND_FLOOR)[:2] == (15, 0)
47
+ assert normalize(0xf1, -4, 4, ROUND_FLOOR)[:2] == (15, 0)
48
+ assert normalize(0xff, -4, 4, ROUND_FLOOR)[:2] == (15, 0)
49
+ assert normalize(-0xf0, -4, 4, ROUND_FLOOR)[:2] == (-15, 0)
50
+ assert normalize(-0xf1, -4, 4, ROUND_FLOOR)[:2] == (-1, 4)
51
+ assert normalize(-0xff, -4, 4, ROUND_FLOOR)[:2] == (-1, 4)
52
+
53
+ def test_round_ceiling():
54
+ assert normalize(0, -4, 4, ROUND_CEILING)[:2] == (0, 0)
55
+ assert normalize(0xf0, -4, 4, ROUND_CEILING)[:2] == (15, 0)
56
+ assert normalize(0xf1, -4, 4, ROUND_CEILING)[:2] == (1, 4)
57
+ assert normalize(0xff, -4, 4, ROUND_CEILING)[:2] == (1, 4)
58
+ assert normalize(-0xf0, -4, 4, ROUND_CEILING)[:2] == (-15, 0)
59
+ assert normalize(-0xf1, -4, 4, ROUND_CEILING)[:2] == (-15, 0)
60
+ assert normalize(-0xff, -4, 4, ROUND_CEILING)[:2] == (-15, 0)
61
+
62
+ def test_round_half_up():
63
+ assert normalize(0, -4, 4, ROUND_HALF_UP)[:2] == (0, 0)
64
+ assert normalize(0xf0, -4, 4, ROUND_HALF_UP)[:2] == (15, 0)
65
+ assert normalize(0xf7, -4, 4, ROUND_HALF_UP)[:2] == (15, 0)
66
+ assert normalize(0xf8, -4, 4, ROUND_HALF_UP)[:2] == (1, 4)
67
+ assert normalize(0xf9, -4, 4, ROUND_HALF_UP)[:2] == (1, 4)
68
+ assert normalize(0xff, -4, 4, ROUND_HALF_UP)[:2] == (1, 4)
69
+ assert normalize(-0xf0, -4, 4, ROUND_HALF_UP)[:2] == (-15, 0)
70
+ assert normalize(-0xf7, -4, 4, ROUND_HALF_UP)[:2] == (-15, 0)
71
+ assert normalize(-0xf8, -4, 4, ROUND_HALF_UP)[:2] == (-1, 4)
72
+ assert normalize(-0xf9, -4, 4, ROUND_HALF_UP)[:2] == (-1, 4)
73
+ assert normalize(-0xff, -4, 4, ROUND_HALF_UP)[:2] == (-1, 4)
74
+
75
+ def test_round_half_down():
76
+ assert normalize(0, -4, 4, ROUND_HALF_DOWN)[:2] == (0, 0)
77
+ assert normalize(0xf0, -4, 4, ROUND_HALF_DOWN)[:2] == (15, 0)
78
+ assert normalize(0xf7, -4, 4, ROUND_HALF_DOWN)[:2] == (15, 0)
79
+ assert normalize(0xf8, -4, 4, ROUND_HALF_DOWN)[:2] == (15, 0)
80
+ assert normalize(0xf9, -4, 4, ROUND_HALF_DOWN)[:2] == (1, 4)
81
+ assert normalize(0xff, -4, 4, ROUND_HALF_DOWN)[:2] == (1, 4)
82
+ assert normalize(-0xf0, -4, 4, ROUND_HALF_DOWN)[:2] == (-15, 0)
83
+ assert normalize(-0xf7, -4, 4, ROUND_HALF_DOWN)[:2] == (-15, 0)
84
+ assert normalize(-0xf8, -4, 4, ROUND_HALF_DOWN)[:2] == (-15, 0)
85
+ assert normalize(-0xf9, -4, 4, ROUND_HALF_DOWN)[:2] == (-1, 4)
86
+ assert normalize(-0xff, -4, 4, ROUND_HALF_DOWN)[:2] == (-1, 4)
87
+
88
+ def test_round_half_even():
89
+ assert normalize(0, -4, 4, ROUND_HALF_EVEN)[:2] == (0, 0)
90
+ assert normalize(0xf0, -4, 4, ROUND_HALF_EVEN)[:2] == (15, 0)
91
+ assert normalize(0xf7, -4, 4, ROUND_HALF_EVEN)[:2] == (15, 0)
92
+ assert normalize(0xf8, -4, 4, ROUND_HALF_EVEN)[:2] == (1, 4) # 1111.1000 -> 10000.0
93
+ assert normalize(0xf9, -4, 4, ROUND_HALF_EVEN)[:2] == (1, 4) # 1111.1001 -> 10000.0
94
+ assert normalize(0xe8, -4, 4, ROUND_HALF_EVEN)[:2] == (7, 1) # 1110.1000 -> 1110.0
95
+ assert normalize(0xe9, -4, 4, ROUND_HALF_EVEN)[:2] == (15, 0) # 1110.1001 -> 1111.0
96
+ assert normalize(-0xf0, -4, 4, ROUND_HALF_EVEN)[:2] == (-15, 0)
97
+ assert normalize(-0xf7, -4, 4, ROUND_HALF_EVEN)[:2] == (-15, 0)
98
+ assert normalize(-0xf8, -4, 4, ROUND_HALF_EVEN)[:2] == (-1, 4)
99
+ assert normalize(-0xf9, -4, 4, ROUND_HALF_EVEN)[:2] == (-1, 4)
100
+ assert normalize(-0xe8, -4, 4, ROUND_HALF_EVEN)[:2] == (-7, 1)
101
+ assert normalize(-0xe9, -4, 4, ROUND_HALF_EVEN)[:2] == (-15, 0)
102
+
103
+ def test_rounding_bugs():
104
+ # 1 less than power-of-two cases
105
+ assert normalize(72057594037927935, -56, 53, ROUND_UP) == (1, 0, 1)
106
+ assert normalize(73786976294838205979L, -65, 53, ROUND_HALF_EVEN) == (1, 1, 1)
107
+ assert normalize(31, 0, 4, ROUND_UP) == (1, 5, 1)
108
+ assert normalize(-31, 0, 4, ROUND_FLOOR) == (-1, 5, 1)
109
+ assert normalize(255, 0, 7, ROUND_UP) == (1, 8, 1)
110
+ assert normalize(-255, 0, 7, ROUND_FLOOR) == (-1, 8, 1)
@@ -0,0 +1,51 @@
1
+ from mpmath import *
2
+ from random import seed, randint, random
3
+
4
+ # Test compatibility with Python floats, which are
5
+ # IEEE doubles (53-bit)
6
+
7
+ N = 5000
8
+ seed(1)
9
+
10
+ # Choosing exponents between roughly -140, 140 ensures that
11
+ # the Python floats don't overflow or underflow
12
+ xs = [(random()-1) * 10**randint(-140, 140) for x in range(N)]
13
+ ys = [(random()-1) * 10**randint(-140, 140) for x in range(N)]
14
+
15
+ # include some equal values
16
+ ys[int(N*0.8):] = xs[int(N*0.8):]
17
+
18
+ def test_double_compatibility():
19
+ mpf.prec = 53
20
+ mpf.round_default()
21
+ for x, y in zip(xs, ys):
22
+ mpx = mpf(x)
23
+ mpy = mpf(y)
24
+ assert mpf(x) == x
25
+ assert (mpx < mpy) == (x < y)
26
+ assert (mpx > mpy) == (x > y)
27
+ assert (mpx == mpy) == (x == y)
28
+ assert (mpx != mpy) == (x != y)
29
+ assert (mpx <= mpy) == (x <= y)
30
+ assert (mpx >= mpy) == (x >= y)
31
+ assert mpx == mpx
32
+ assert mpx + mpy == x + y
33
+ assert mpx * mpy == x * y
34
+ assert mpx / mpy == x / y
35
+ assert abs(mpx) == abs(x)
36
+ assert mpf(repr(x)) == x
37
+
38
+ def test_sqrt():
39
+ # this fails roughly 1 time out of 1000. it appers to be float
40
+ # that rounds the wrong way, not mpf
41
+ fail = 0
42
+ mpf.prec = 53
43
+ mpf.round_default()
44
+ for x in xs:
45
+ fail += (abs(mpf(x))**0.5 != abs(x)**0.5)
46
+ assert fail < 2*(N/1000.0)
47
+
48
+ def test_bugs():
49
+ # particular bugs
50
+ assert mpf(4.4408920985006262E-16) < mpf(1.7763568394002505E-15)
51
+ assert mpf(-4.4408920985006262E-16) > mpf(-1.7763568394002505E-15)
@@ -0,0 +1,62 @@
1
+ import random
2
+ from mpmath import *
3
+ from mpmath.lib import *
4
+
5
+
6
+ def test_basic_string():
7
+ """
8
+ Test basic string conversion
9
+ """
10
+ assert mpf('3') == mpf('3.0') == mpf('0003.') == mpf('0.03e2') == mpf(3.0)
11
+ assert mpf('30') == mpf('30.0') == mpf('00030.') == mpf(30.0)
12
+ for i in range(10):
13
+ for j in range(10):
14
+ assert mpf('%ie%i' % (i,j)) == i * 10**j
15
+ assert str(mpf('25000.0')) == '25000.0'
16
+ assert str(mpf('2500.0')) == '2500.0'
17
+ assert str(mpf('250.0')) == '250.0'
18
+ assert str(mpf('25.0')) == '25.0'
19
+ assert str(mpf('2.5')) == '2.5'
20
+ assert str(mpf('0.25')) == '0.25'
21
+ assert str(mpf('0.025')) == '0.025'
22
+ assert str(mpf('0.0025')) == '0.0025'
23
+ assert str(mpf('0.00025')) == '0.00025'
24
+ assert str(mpf('0.000025')) == '2.5e-5'
25
+ assert str(mpf(0)) == '0.0'
26
+ assert str(mpf('2.5e1000000000000000000000')) == '2.5e+1000000000000000000000'
27
+ assert str(mpf('2.6e-1000000000000000000000')) == '2.6e-1000000000000000000000'
28
+ assert str(mpf(1.23402834e-15)) == '1.23402834e-15'
29
+ assert str(mpf(-1.23402834e-15)) == '-1.23402834e-15'
30
+ assert str(mpf(-1.2344e-15)) == '-1.2344e-15'
31
+ assert repr(mpf(-1.2344e-15)) == "mpf('-1.2343999999999999e-15')"
32
+
33
+
34
+ def test_tight_string_conversion():
35
+ # In an old version, '0.5' wasn't recognized as representing
36
+ # an exact binary number and was erroneously rounded up or down
37
+ assert from_str('0.5', 10, ROUND_FLOOR) == fhalf
38
+ assert from_str('0.5', 10, ROUND_CEILING) == fhalf
39
+
40
+
41
+ def test_eval_repr_invariant():
42
+ """Test that eval(repr(x)) == x"""
43
+ random.seed(123)
44
+ for dps in [10, 15, 20, 50, 100]:
45
+ mpf.dps = dps
46
+ for i in xrange(1000):
47
+ a = mpf(random.random())**0.5 * 10**random.randint(-100, 100)
48
+ if dps == 15:
49
+ assert eval(repr(a)) == a
50
+ else:
51
+ assert eval(repr(a)).ae(a)
52
+
53
+ def test_str_bugs():
54
+ # Decimal rounding used to give the wrong exponent in some cases
55
+ assert str(mpf('1e600')) == '1.0e+600'
56
+ assert str(mpf('1e10000')) == '1.0e+10000'
57
+
58
+
59
+ def test_convert_rational():
60
+ assert from_rational(30, 5, 53, ROUND_HALF_EVEN) == (3, 1, 2)
61
+ assert from_rational(-7, 4, 53, ROUND_HALF_EVEN) == (-7, -2, 3)
62
+ assert to_rational((1, -1, 1)) == (1, 2)
@@ -0,0 +1,126 @@
1
+ from mpmath.lib import *
2
+
3
+ from random import randint, choice, seed
4
+
5
+ all_modes = [ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP,
6
+ ROUND_HALF_DOWN, ROUND_HALF_UP, ROUND_HALF_EVEN]
7
+
8
+ fb = from_bstr
9
+ fi = from_int_exact
10
+ ff = from_float
11
+
12
+
13
+ def test_div_1_3():
14
+ a = fi(1)
15
+ b = fi(3)
16
+ c = fi(-1)
17
+
18
+ # Floor rounds down, ceiling rounds up
19
+ assert fdiv(a, b, 7, ROUND_FLOOR) == fb('0.01010101')
20
+ assert fdiv(a, b, 7, ROUND_CEILING) == fb('0.01010110')
21
+ assert fdiv(a, b, 7, ROUND_DOWN) == fb('0.01010101')
22
+ assert fdiv(a, b, 7, ROUND_UP) == fb('0.01010110')
23
+ assert fdiv(a, b, 7, ROUND_HALF_DOWN) == fb('0.01010101')
24
+ assert fdiv(a, b, 7, ROUND_HALF_UP) == fb('0.01010101')
25
+ assert fdiv(a, b, 7, ROUND_HALF_EVEN) == fb('0.01010101')
26
+
27
+ # Floor rounds up, ceiling rounds down
28
+ assert fdiv(c, b, 7, ROUND_FLOOR) == fb('-0.01010110')
29
+ assert fdiv(c, b, 7, ROUND_CEILING) == fb('-0.01010101')
30
+ assert fdiv(c, b, 7, ROUND_DOWN) == fb('-0.01010101')
31
+ assert fdiv(c, b, 7, ROUND_UP) == fb('-0.01010110')
32
+ assert fdiv(c, b, 7, ROUND_HALF_DOWN) == fb('-0.01010101')
33
+ assert fdiv(c, b, 7, ROUND_HALF_UP) == fb('-0.01010101')
34
+ assert fdiv(c, b, 7, ROUND_HALF_EVEN) == fb('-0.01010101')
35
+
36
+
37
+ def test_div_300():
38
+
39
+ q = fi(1000000)
40
+ a = fi(300499999) # a/q is a little less than a half-integer
41
+ b = fi(300500000) # b/q exactly a half-integer
42
+ c = fi(300500001) # c/q is a little more than a half-integer
43
+
44
+ # Check nearest integer rounding (prec=9 as 2**8 < 300 < 2**9)
45
+
46
+ assert fdiv(a, q, 9, ROUND_DOWN) == fi(300)
47
+ assert fdiv(b, q, 9, ROUND_DOWN) == fi(300)
48
+ assert fdiv(c, q, 9, ROUND_DOWN) == fi(300)
49
+ assert fdiv(a, q, 9, ROUND_UP) == fi(301)
50
+ assert fdiv(b, q, 9, ROUND_UP) == fi(301)
51
+ assert fdiv(c, q, 9, ROUND_UP) == fi(301)
52
+ assert fdiv(a, q, 9, ROUND_HALF_UP) == fi(300)
53
+ assert fdiv(b, q, 9, ROUND_HALF_UP) == fi(301)
54
+ assert fdiv(c, q, 9, ROUND_HALF_UP) == fi(301)
55
+ assert fdiv(a, q, 9, ROUND_HALF_DOWN) == fi(300)
56
+ assert fdiv(b, q, 9, ROUND_HALF_DOWN) == fi(300)
57
+ assert fdiv(c, q, 9, ROUND_HALF_DOWN) == fi(301)
58
+
59
+ # Nearest even integer is down
60
+ assert fdiv(a, q, 9, ROUND_HALF_EVEN) == fi(300)
61
+ assert fdiv(b, q, 9, ROUND_HALF_EVEN) == fi(300)
62
+ assert fdiv(c, q, 9, ROUND_HALF_EVEN) == fi(301)
63
+
64
+ # Nearest even integer is up
65
+ a = fi(301499999)
66
+ b = fi(301500000)
67
+ c = fi(301500001)
68
+ assert fdiv(a, q, 9, ROUND_HALF_EVEN) == fi(301)
69
+ assert fdiv(b, q, 9, ROUND_HALF_EVEN) == fi(302)
70
+ assert fdiv(c, q, 9, ROUND_HALF_EVEN) == fi(302)
71
+
72
+
73
+ def test_tight_integer_division():
74
+ # Test that integer division at tightest possible precision is exact
75
+ N = 100
76
+ seed(1)
77
+ for i in range(N):
78
+ a = choice([1, -1]) * randint(1, 1<<randint(10, 100))
79
+ b = choice([1, -1]) * randint(1, 1<<randint(10, 100))
80
+ p = a * b
81
+ width = bitcount(b) - trailing_zeros(b)
82
+ a = fi(a); b = fi(b); p = fi(p)
83
+ for mode in all_modes:
84
+ assert fdiv(p, a, width, mode) == b
85
+
86
+
87
+ def test_epsilon_rounding():
88
+ # Verify that fdiv uses infinite precision; this result will
89
+ # appear to be exactly 0.101 to a near-sighted algorithm
90
+
91
+ a = fb('0.101' + ('0'*200) + '1')
92
+ b = fb('1.10101')
93
+ c = fmul(a, b, 250, ROUND_FLOOR) # Exact
94
+ assert fdiv(c, b, bitcount(a[0]), ROUND_FLOOR) == a # Exact
95
+
96
+ # Not exactly half, so both must round up
97
+ assert fdiv(c, b, 2, ROUND_HALF_DOWN) == fb('0.11')
98
+ assert fdiv(c, b, 2, ROUND_HALF_UP) == fb('0.11')
99
+
100
+ assert fdiv(c, b, 2, ROUND_DOWN) == fb('0.10')
101
+ assert fdiv(c, b, 3, ROUND_DOWN) == fb('0.101')
102
+ assert fdiv(c, b, 2, ROUND_UP) == fb('0.11')
103
+ assert fdiv(c, b, 3, ROUND_UP) == fb('0.110')
104
+ assert fdiv(c, b, 2, ROUND_FLOOR) == fb('0.10')
105
+ assert fdiv(c, b, 3, ROUND_FLOOR) == fb('0.101')
106
+ assert fdiv(c, b, 2, ROUND_CEILING) == fb('0.11')
107
+ assert fdiv(c, b, 3, ROUND_CEILING) == fb('0.110')
108
+
109
+ # The same for negative numbers
110
+ a = fb('-0.101' + ('0'*200) + '1')
111
+ b = fb('1.10101')
112
+ c = fmul(a, b, 250, ROUND_FLOOR)
113
+ assert fdiv(c, b, bitcount(a[0]), ROUND_FLOOR) == a
114
+
115
+ # Both must round away from zero
116
+ assert fdiv(c, b, 2, ROUND_HALF_DOWN) == fb('-0.11')
117
+ assert fdiv(c, b, 2, ROUND_HALF_UP) == fb('-0.11')
118
+
119
+ assert fdiv(c, b, 2, ROUND_DOWN) == fb('-0.10')
120
+ assert fdiv(c, b, 3, ROUND_UP) == fb('-0.110')
121
+
122
+ # Floor goes up, ceiling goes down
123
+ assert fdiv(c, b, 2, ROUND_FLOOR) == fb('-0.11')
124
+ assert fdiv(c, b, 3, ROUND_FLOOR) == fb('-0.110')
125
+ assert fdiv(c, b, 2, ROUND_CEILING) == fb('-0.10')
126
+ assert fdiv(c, b, 3, ROUND_CEILING) == fb('-0.101')
@@ -0,0 +1,68 @@
1
+ import math
2
+ from mpmath import *
3
+
4
+ def test_incomplete_gamma():
5
+ mpf.dps = 15
6
+ assert upper_gamma(-2.5,-0.5).ae(-0.9453087204829418812-5.3164237738936178621j)
7
+ assert erf(0) == 0
8
+ assert erf(1).ae(0.84270079294971486934)
9
+ assert erf(3+4j).ae(-120.186991395079444098 - 27.750337293623902498j)
10
+ assert erf(-4-3j).ae(-0.99991066178539168236 + 0.00004972026054496604j)
11
+ assert erf(pi).ae(0.99999112385363235839)
12
+ assert erf(1j).ae(1.6504257587975428760j)
13
+ assert erf(-1j).ae(-1.6504257587975428760j)
14
+ assert isinstance(erf(1), mpf)
15
+ assert isinstance(erf(-1), mpf)
16
+ assert isinstance(erf(0), mpf)
17
+ assert isinstance(erf(0j), mpc)
18
+
19
+ def test_gamma():
20
+ mpf.dps = 15
21
+ assert gamma(0.25).ae(3.6256099082219083119)
22
+ assert gamma(0.0001).ae(9999.4228832316241908)
23
+ assert gamma(300).ae('1.0201917073881354535e612')
24
+ assert gamma(-0.5).ae(-3.5449077018110320546)
25
+ assert gamma(-7.43).ae(0.00026524416464197007186)
26
+ #assert gamma(Rational(1,2)) == gamma(0.5)
27
+ #assert gamma(Rational(-7,3)).ae(gamma(mpf(-7)/3))
28
+ assert gamma(1+1j).ae(0.49801566811835604271 - 0.15494982830181068512j)
29
+ assert gamma(-1+0.01j).ae(-0.422733904013474115 + 99.985883082635367436j)
30
+ assert gamma(20+30j).ae(-1453876687.5534810 + 1163777777.8031573j)
31
+ # Should always give exact factorials when they can
32
+ # be represented as mpfs under the current working precision
33
+ fact = 1
34
+ for i in range(1, 18):
35
+ assert gamma(i) == fact
36
+ fact *= i
37
+ for dps in [170, 600]:
38
+ fact = 1
39
+ mpf.dps = dps
40
+ for i in range(1, 105):
41
+ assert gamma(i) == fact
42
+ fact *= i
43
+ mpf.dps = 100
44
+ assert gamma(0.5).ae(sqrt(pi))
45
+ mpf.dps = 15
46
+ assert factorial(0) == 1
47
+ assert factorial(3) == 6
48
+
49
+ def test_zeta():
50
+ mpf.dps = 15
51
+ assert zeta(2).ae(pi**2 / 6)
52
+ assert zeta(2.0).ae(pi**2 / 6)
53
+ assert zeta(mpc(2)).ae(pi**2 / 6)
54
+ assert zeta(100).ae(1)
55
+ assert zeta(0).ae(-0.5)
56
+ assert zeta(0.5).ae(-1.46035450880958681)
57
+ assert zeta(-1).ae(-mpf(1)/12)
58
+ assert zeta(-2).ae(0)
59
+ assert zeta(-3).ae(mpf(1)/120)
60
+ assert zeta(-4).ae(0)
61
+ # Zeros in the critical strip
62
+ assert zeta(mpc(0.5, 14.1347251417346937904)).ae(0)
63
+ assert zeta(mpc(0.5, 21.0220396387715549926)).ae(0)
64
+ assert zeta(mpc(0.5, 25.0108575801456887632)).ae(0)
65
+ mpf.dps = 50
66
+ im = '236.5242296658162058024755079556629786895294952121891237'
67
+ assert zeta(mpc(0.5, im)).ae(0, 1e-46)
68
+ mpf.dps = 15