I am done

This commit is contained in:
2024-10-30 22:14:35 +01:00
parent 720dc28c09
commit 40e2a747cf
36901 changed files with 5011519 additions and 0 deletions

View File

@ -0,0 +1,215 @@
from mpmath import *
from mpmath.libmp import ifac
import sys
if "-dps" in sys.argv:
maxdps = int(sys.argv[sys.argv.index("-dps")+1])
else:
maxdps = 1000
raise_ = "-raise" in sys.argv
errcount = 0
def check(name, func, z, y):
global errcount
try:
x = func(z)
except:
errcount += 1
if raise_:
raise
print()
print(name)
print("EXCEPTION")
import traceback
traceback.print_tb(sys.exc_info()[2])
print()
return
xre = x.real
xim = x.imag
yre = y.real
yim = y.imag
tol = eps*8
err = 0
if abs(xre-yre) > abs(yre)*tol:
err = 1
print()
print("Error! %s (re = %s, wanted %s, err=%s)" % (name, nstr(xre,10), nstr(yre,10), nstr(abs(xre-yre))))
errcount += 1
if raise_:
raise SystemExit
if abs(xim-yim) > abs(yim)*tol:
err = 1
print()
print("Error! %s (im = %s, wanted %s, err=%s)" % (name, nstr(xim,10), nstr(yim,10), nstr(abs(xim-yim))))
errcount += 1
if raise_:
raise SystemExit
if not err:
sys.stdout.write("%s ok; " % name)
def testcase(case):
z, result = case
print("Testing z =", z)
mp.dps = 1010
z = eval(z)
mp.dps = maxdps + 50
if result is None:
gamma_val = gamma(z)
loggamma_val = loggamma(z)
factorial_val = factorial(z)
rgamma_val = rgamma(z)
else:
loggamma_val = eval(result)
gamma_val = exp(loggamma_val)
factorial_val = z * gamma_val
rgamma_val = 1/gamma_val
for dps in [5, 10, 15, 25, 40, 60, 90, 120, 250, 600, 1000, 1800, 3600]:
if dps > maxdps:
break
mp.dps = dps
print("dps = %s" % dps)
check("gamma", gamma, z, gamma_val)
check("rgamma", rgamma, z, rgamma_val)
check("loggamma", loggamma, z, loggamma_val)
check("factorial", factorial, z, factorial_val)
print()
mp.dps = 15
testcases = []
# Basic values
for n in list(range(1,200)) + list(range(201,2000,17)):
testcases.append(["%s" % n, None])
for n in range(-200,200):
testcases.append(["%s+0.5" % n, None])
testcases.append(["%s+0.37" % n, None])
testcases += [\
["(0.1+1j)", None],
["(-0.1+1j)", None],
["(0.1-1j)", None],
["(-0.1-1j)", None],
["10j", None],
["-10j", None],
["100j", None],
["10000j", None],
["-10000000j", None],
["(10**100)*j", None],
["125+(10**100)*j", None],
["-125+(10**100)*j", None],
["(10**10)*(1+j)", None],
["(10**10)*(-1+j)", None],
["(10**100)*(1+j)", None],
["(10**100)*(-1+j)", None],
["(1.5-1j)", None],
["(6+4j)", None],
["(4+1j)", None],
["(3.5+2j)", None],
["(1.5-1j)", None],
["(-6-4j)", None],
["(-2-3j)", None],
["(-2.5-2j)", None],
["(4+1j)", None],
["(3+3j)", None],
["(2-2j)", None],
["1", "0"],
["2", "0"],
["3", "log(2)"],
["4", "log(6)"],
["5", "log(24)"],
["0.5", "log(pi)/2"],
["1.5", "log(sqrt(pi)/2)"],
["2.5", "log(3*sqrt(pi)/4)"],
["mpf('0.37')", None],
["0.25", "log(sqrt(2*sqrt(2*pi**3)/agm(1,sqrt(2))))"],
["-0.4", None],
["mpf('-1.9')", None],
["mpf('12.8')", None],
["mpf('33.7')", None],
["mpf('95.2')", None],
["mpf('160.3')", None],
["mpf('2057.8')", None],
["25", "log(ifac(24))"],
["80", "log(ifac(79))"],
["500", "log(ifac(500-1))"],
["8000", "log(ifac(8000-1))"],
["8000.5", None],
["mpf('8000.1')", None],
["mpf('1.37e10')", None],
["mpf('1.37e10')*(1+j)", None],
["mpf('1.37e10')*(-1+j)", None],
["mpf('1.37e10')*(-1-j)", None],
["mpf('1.37e10')*(-1+j)", None],
["mpf('1.37e100')", None],
["mpf('1.37e100')*(1+j)", None],
["mpf('1.37e100')*(-1+j)", None],
["mpf('1.37e100')*(-1-j)", None],
["mpf('1.37e100')*(-1+j)", None],
["3+4j",
"mpc('"
"-1.7566267846037841105306041816232757851567066070613445016197619371316057169"
"4723618263960834804618463052988607348289672535780644470689771115236512106002"
"5970873471563240537307638968509556191696167970488390423963867031934333890838"
"8009531786948197210025029725361069435208930363494971027388382086721660805397"
"9163230643216054580167976201709951509519218635460317367338612500626714783631"
"7498317478048447525674016344322545858832610325861086336204591943822302971823"
"5161814175530618223688296232894588415495615809337292518431903058265147109853"
"1710568942184987827643886816200452860853873815413367529829631430146227470517"
"6579967222200868632179482214312673161276976117132204633283806161971389519137"
"1243359764435612951384238091232760634271570950240717650166551484551654327989"
"9360285030081716934130446150245110557038117075172576825490035434069388648124"
"6678152254554001586736120762641422590778766100376515737713938521275749049949"
"1284143906816424244705094759339932733567910991920631339597278805393743140853"
"391550313363278558195609260225928','"
"4.74266443803465792819488940755002274088830335171164611359052405215840070271"
"5906813009373171139767051863542508136875688550817670379002790304870822775498"
"2809996675877564504192565392367259119610438951593128982646945990372179860613"
"4294436498090428077839141927485901735557543641049637962003652638924845391650"
"9546290137755550107224907606529385248390667634297183361902055842228798984200"
"9591180450211798341715874477629099687609819466457990642030707080894518168924"
"6805549314043258530272479246115112769957368212585759640878745385160943755234"
"9398036774908108204370323896757543121853650025529763655312360354244898913463"
"7115955702828838923393113618205074162812089732064414530813087483533203244056"
"0546577484241423134079056537777170351934430586103623577814746004431994179990"
"5318522939077992613855205801498201930221975721246498720895122345420698451980"
"0051215797310305885845964334761831751370672996984756815410977750799748813563"
"8784405288158432214886648743541773208808731479748217023665577802702269468013"
"673719173759245720489020315779001')"],
]
for z in [4, 14, 34, 64]:
testcases.append(["(2+j)*%s/3" % z, None])
testcases.append(["(-2+j)*%s/3" % z, None])
testcases.append(["(1+2*j)*%s/3" % z, None])
testcases.append(["(2-j)*%s/3" % z, None])
testcases.append(["(20+j)*%s/3" % z, None])
testcases.append(["(-20+j)*%s/3" % z, None])
testcases.append(["(1+20*j)*%s/3" % z, None])
testcases.append(["(20-j)*%s/3" % z, None])
testcases.append(["(200+j)*%s/3" % z, None])
testcases.append(["(-200+j)*%s/3" % z, None])
testcases.append(["(1+200*j)*%s/3" % z, None])
testcases.append(["(200-j)*%s/3" % z, None])
# Poles
for n in [0,1,2,3,4,25,-1,-2,-3,-4,-20,-21,-50,-51,-200,-201,-20000,-20001]:
for t in ['1e-5', '1e-20', '1e-100', '1e-10000']:
testcases.append(["fadd(%s,'%s',exact=True)" % (n, t), None])
testcases.append(["fsub(%s,'%s',exact=True)" % (n, t), None])
testcases.append(["fadd(%s,'%sj',exact=True)" % (n, t), None])
testcases.append(["fsub(%s,'%sj',exact=True)" % (n, t), None])
if __name__ == "__main__":
from timeit import default_timer as clock
tot_time = 0.0
for case in testcases:
t1 = clock()
testcase(case)
t2 = clock()
print("Test time:", t2-t1)
print()
tot_time += (t2-t1)
print("Total time:", tot_time)
print("Errors:", errcount)

View File

@ -0,0 +1,30 @@
from mpmath import zetazero
from timeit import default_timer as clock
def test_zetazero():
cases = [\
(399999999, 156762524.6750591511),
(241389216, 97490234.2276711795),
(526196239, 202950727.691229534),
(542964976, 209039046.578535272),
(1048449112, 388858885.231056486),
(1048449113, 388858885.384337406),
(1048449114, 388858886.002285122),
(1048449115, 388858886.00239369),
(1048449116, 388858886.690745053)
]
for n, v in cases:
print(n, v)
t1 = clock()
ok = zetazero(n).ae(complex(0.5,v))
t2 = clock()
print("ok =", ok, ("(time = %s)" % round(t2-t1,3)))
print("Now computing two huge zeros (this may take hours)")
print("Computing zetazero(8637740722917)")
ok = zetazero(8637740722917).ae(complex(0.5,2124447368584.39296466152))
print("ok =", ok)
ok = zetazero(8637740722918).ae(complex(0.5,2124447368584.39298170604))
print("ok =", ok)
if __name__ == "__main__":
test_zetazero()

View File

@ -0,0 +1,161 @@
#!/usr/bin/env python
"""
python runtests.py -py
Use py.test to run tests (more useful for debugging)
python runtests.py -coverage
Generate test coverage report. Statistics are written to /tmp
python runtests.py -profile
Generate profile stats (this is much slower)
python runtests.py -nogmpy
Run tests without using GMPY even if it exists
python runtests.py -strict
Enforce extra tests in normalize()
python runtests.py -local
Insert '../..' at the beginning of sys.path to use local mpmath
python runtests.py -skip ...
Skip tests from the listed modules
Additional arguments are used to filter the tests to run. Only files that have
one of the arguments in their name are executed.
"""
import sys, os, traceback
profile = False
if "-profile" in sys.argv:
sys.argv.remove('-profile')
profile = True
coverage = False
if "-coverage" in sys.argv:
sys.argv.remove('-coverage')
coverage = True
if "-nogmpy" in sys.argv:
sys.argv.remove('-nogmpy')
os.environ['MPMATH_NOGMPY'] = 'Y'
if "-strict" in sys.argv:
sys.argv.remove('-strict')
os.environ['MPMATH_STRICT'] = 'Y'
if "-local" in sys.argv:
sys.argv.remove('-local')
importdir = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]),
'../..'))
else:
importdir = ''
# TODO: add a flag for this
testdir = ''
def testit(importdir='', testdir='', exit_on_fail=False):
"""Run all tests in testdir while importing from importdir."""
if importdir:
sys.path.insert(1, importdir)
if testdir:
sys.path.insert(1, testdir)
import os.path
import mpmath
print("mpmath imported from %s" % os.path.dirname(mpmath.__file__))
print("mpmath backend: %s" % mpmath.libmp.backend.BACKEND)
print("mpmath mp class: %s" % repr(mpmath.mp))
print("mpmath version: %s" % mpmath.__version__)
print("Python version: %s" % sys.version)
print("")
if "-py" in sys.argv:
sys.argv.remove('-py')
import py
py.test.cmdline.main()
else:
import glob
from timeit import default_timer as clock
modules = []
args = sys.argv[1:]
excluded = []
if '-skip' in args:
excluded = args[args.index('-skip')+1:]
args = args[:args.index('-skip')]
# search for tests in directory of this file if not otherwise specified
if not testdir:
pattern = os.path.dirname(sys.argv[0])
else:
pattern = testdir
if pattern:
pattern += '/'
pattern += 'test*.py'
# look for tests (respecting specified filter)
for f in glob.glob(pattern):
name = os.path.splitext(os.path.basename(f))[0]
# If run as a script, only run tests given as args, if any are given
if args and __name__ == "__main__":
ok = False
for arg in args:
if arg in name:
ok = True
break
if not ok:
continue
elif name in excluded:
continue
module = __import__(name)
priority = module.__dict__.get('priority', 100)
if priority == 666:
modules = [[priority, name, module]]
break
modules.append([priority, name, module])
# execute tests
modules.sort()
tstart = clock()
for priority, name, module in modules:
print(name)
for f in sorted(module.__dict__.keys()):
if f.startswith('test_'):
if coverage and ('numpy' in f):
continue
sys.stdout.write(" " + f[5:].ljust(25) + " ")
t1 = clock()
try:
module.__dict__[f]()
except:
etype, evalue, trb = sys.exc_info()
if etype in (KeyboardInterrupt, SystemExit):
raise
print("")
print("TEST FAILED!")
print("")
traceback.print_exc()
if exit_on_fail:
return
t2 = clock()
print("ok " + " " + ("%.7f" % (t2-t1)) + " s")
tend = clock()
print("")
print("finished tests in " + ("%.2f" % (tend-tstart)) + " seconds")
# clean sys.path
if importdir:
sys.path.remove(importdir)
if testdir:
sys.path.remove(testdir)
if __name__ == '__main__':
if profile:
import cProfile
cProfile.run("testit('%s', '%s')" % (importdir, testdir), sort=1)
elif coverage:
import trace
tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix],
trace=0, count=1)
tracer.run('testit(importdir, testdir)')
r = tracer.results()
r.write_results(show_missing=True, summary=True, coverdir="/tmp")
else:
testit(importdir, testdir)

View File

@ -0,0 +1,451 @@
import mpmath
from mpmath import *
from mpmath.libmp import *
import random
import sys
try:
long = long
except NameError:
long = int
def test_type_compare():
assert mpf(2) == mpc(2,0)
assert mpf(0) == mpc(0)
assert mpf(2) != mpc(2, 0.00001)
assert mpf(2) == 2.0
assert mpf(2) != 3.0
assert mpf(2) == 2
assert mpf(2) != '2.0'
assert mpc(2) != '2.0'
def test_add():
assert mpf(2.5) + mpf(3) == 5.5
assert mpf(2.5) + 3 == 5.5
assert mpf(2.5) + 3.0 == 5.5
assert 3 + mpf(2.5) == 5.5
assert 3.0 + mpf(2.5) == 5.5
assert (3+0j) + mpf(2.5) == 5.5
assert mpc(2.5) + mpf(3) == 5.5
assert mpc(2.5) + 3 == 5.5
assert mpc(2.5) + 3.0 == 5.5
assert mpc(2.5) + (3+0j) == 5.5
assert 3 + mpc(2.5) == 5.5
assert 3.0 + mpc(2.5) == 5.5
assert (3+0j) + mpc(2.5) == 5.5
def test_sub():
assert mpf(2.5) - mpf(3) == -0.5
assert mpf(2.5) - 3 == -0.5
assert mpf(2.5) - 3.0 == -0.5
assert 3 - mpf(2.5) == 0.5
assert 3.0 - mpf(2.5) == 0.5
assert (3+0j) - mpf(2.5) == 0.5
assert mpc(2.5) - mpf(3) == -0.5
assert mpc(2.5) - 3 == -0.5
assert mpc(2.5) - 3.0 == -0.5
assert mpc(2.5) - (3+0j) == -0.5
assert 3 - mpc(2.5) == 0.5
assert 3.0 - mpc(2.5) == 0.5
assert (3+0j) - mpc(2.5) == 0.5
def test_mul():
assert mpf(2.5) * mpf(3) == 7.5
assert mpf(2.5) * 3 == 7.5
assert mpf(2.5) * 3.0 == 7.5
assert 3 * mpf(2.5) == 7.5
assert 3.0 * mpf(2.5) == 7.5
assert (3+0j) * mpf(2.5) == 7.5
assert mpc(2.5) * mpf(3) == 7.5
assert mpc(2.5) * 3 == 7.5
assert mpc(2.5) * 3.0 == 7.5
assert mpc(2.5) * (3+0j) == 7.5
assert 3 * mpc(2.5) == 7.5
assert 3.0 * mpc(2.5) == 7.5
assert (3+0j) * mpc(2.5) == 7.5
def test_div():
assert mpf(6) / mpf(3) == 2.0
assert mpf(6) / 3 == 2.0
assert mpf(6) / 3.0 == 2.0
assert 6 / mpf(3) == 2.0
assert 6.0 / mpf(3) == 2.0
assert (6+0j) / mpf(3.0) == 2.0
assert mpc(6) / mpf(3) == 2.0
assert mpc(6) / 3 == 2.0
assert mpc(6) / 3.0 == 2.0
assert mpc(6) / (3+0j) == 2.0
assert 6 / mpc(3) == 2.0
assert 6.0 / mpc(3) == 2.0
assert (6+0j) / mpc(3) == 2.0
def test_pow():
assert mpf(6) ** mpf(3) == 216.0
assert mpf(6) ** 3 == 216.0
assert mpf(6) ** 3.0 == 216.0
assert 6 ** mpf(3) == 216.0
assert 6.0 ** mpf(3) == 216.0
assert (6+0j) ** mpf(3.0) == 216.0
assert mpc(6) ** mpf(3) == 216.0
assert mpc(6) ** 3 == 216.0
assert mpc(6) ** 3.0 == 216.0
assert mpc(6) ** (3+0j) == 216.0
assert 6 ** mpc(3) == 216.0
assert 6.0 ** mpc(3) == 216.0
assert (6+0j) ** mpc(3) == 216.0
def test_mixed_misc():
assert 1 + mpf(3) == mpf(3) + 1 == 4
assert 1 - mpf(3) == -(mpf(3) - 1) == -2
assert 3 * mpf(2) == mpf(2) * 3 == 6
assert 6 / mpf(2) == mpf(6) / 2 == 3
assert 1.0 + mpf(3) == mpf(3) + 1.0 == 4
assert 1.0 - mpf(3) == -(mpf(3) - 1.0) == -2
assert 3.0 * mpf(2) == mpf(2) * 3.0 == 6
assert 6.0 / mpf(2) == mpf(6) / 2.0 == 3
def test_add_misc():
mp.dps = 15
assert mpf(4) + mpf(-70) == -66
assert mpf(1) + mpf(1.1)/80 == 1 + 1.1/80
assert mpf((1, 10000000000)) + mpf(3) == mpf((1, 10000000000))
assert mpf(3) + mpf((1, 10000000000)) == mpf((1, 10000000000))
assert mpf((1, -10000000000)) + mpf(3) == mpf(3)
assert mpf(3) + mpf((1, -10000000000)) == mpf(3)
assert mpf(1) + 1e-15 != 1
assert mpf(1) + 1e-20 == 1
assert mpf(1.07e-22) + 0 == mpf(1.07e-22)
assert mpf(0) + mpf(1.07e-22) == mpf(1.07e-22)
def test_complex_misc():
# many more tests needed
assert 1 + mpc(2) == 3
assert not mpc(2).ae(2 + 1e-13)
assert mpc(2+1e-15j).ae(2)
def test_complex_zeros():
for a in [0,2]:
for b in [0,3]:
for c in [0,4]:
for d in [0,5]:
assert mpc(a,b)*mpc(c,d) == complex(a,b)*complex(c,d)
def test_hash():
for i in range(-256, 256):
assert hash(mpf(i)) == hash(i)
assert hash(mpf(0.5)) == hash(0.5)
assert hash(mpc(2,3)) == hash(2+3j)
# Check that this doesn't fail
assert hash(inf)
# Check that overflow doesn't assign equal hashes to large numbers
assert hash(mpf('1e1000')) != hash('1e10000')
assert hash(mpc(100,'1e1000')) != hash(mpc(200,'1e1000'))
from mpmath.rational import mpq
assert hash(mp.mpq(1,3))
assert hash(mp.mpq(0,1)) == 0
assert hash(mp.mpq(-1,1)) == hash(-1)
assert hash(mp.mpq(1,1)) == hash(1)
assert hash(mp.mpq(5,1)) == hash(5)
assert hash(mp.mpq(1,2)) == hash(0.5)
if sys.version_info >= (3, 2):
assert hash(mpf(1)*2**2000) == hash(2**2000)
assert hash(mpf(1)/2**2000) == hash(mpq(1,2**2000))
# Advanced rounding test
def test_add_rounding():
mp.dps = 15
a = from_float(1e-50)
assert mpf_sub(mpf_add(fone, a, 53, round_up), fone, 53, round_up) == from_float(2.2204460492503131e-16)
assert mpf_sub(fone, a, 53, round_up) == fone
assert mpf_sub(fone, mpf_sub(fone, a, 53, round_down), 53, round_down) == from_float(1.1102230246251565e-16)
assert mpf_add(fone, a, 53, round_down) == fone
def test_almost_equal():
assert mpf(1.2).ae(mpf(1.20000001), 1e-7)
assert not mpf(1.2).ae(mpf(1.20000001), 1e-9)
assert not mpf(-0.7818314824680298).ae(mpf(-0.774695868667929))
def test_arithmetic_functions():
import operator
ops = [(operator.add, fadd), (operator.sub, fsub), (operator.mul, fmul),
(operator.truediv, fdiv)]
a = mpf(0.27)
b = mpf(1.13)
c = mpc(0.51+2.16j)
d = mpc(1.08-0.99j)
for x in [a,b,c,d]:
for y in [a,b,c,d]:
for op, fop in ops:
if fop is not fdiv:
mp.prec = 200
z0 = op(x,y)
mp.prec = 60
z1 = op(x,y)
mp.prec = 53
z2 = op(x,y)
assert fop(x, y, prec=60) == z1
assert fop(x, y) == z2
if fop is not fdiv:
assert fop(x, y, prec=inf) == z0
assert fop(x, y, dps=inf) == z0
assert fop(x, y, exact=True) == z0
assert fneg(fneg(z1, exact=True), prec=inf) == z1
assert fneg(z1) == -(+z1)
mp.dps = 15
def test_exact_integer_arithmetic():
# XXX: re-fix this so that all operations are tested with all rounding modes
random.seed(0)
for prec in [6, 10, 25, 40, 100, 250, 725]:
for rounding in ['d', 'u', 'f', 'c', 'n']:
mp.dps = prec
M = 10**(prec-2)
M2 = 10**(prec//2-2)
for i in range(10):
a = random.randint(-M, M)
b = random.randint(-M, M)
assert mpf(a, rounding=rounding) == a
assert int(mpf(a, rounding=rounding)) == a
assert int(mpf(str(a), rounding=rounding)) == a
assert mpf(a) + mpf(b) == a + b
assert mpf(a) - mpf(b) == a - b
assert -mpf(a) == -a
a = random.randint(-M2, M2)
b = random.randint(-M2, M2)
assert mpf(a) * mpf(b) == a*b
assert mpf_mul(from_int(a), from_int(b), mp.prec, rounding) == from_int(a*b)
mp.dps = 15
def test_odd_int_bug():
assert to_int(from_int(3), round_nearest) == 3
def test_str_1000_digits():
mp.dps = 1001
# last digit may be wrong
assert str(mpf(2)**0.5)[-10:-1] == '9518488472'[:9]
assert str(pi)[-10:-1] == '2164201989'[:9]
mp.dps = 15
def test_str_10000_digits():
mp.dps = 10001
# last digit may be wrong
assert str(mpf(2)**0.5)[-10:-1] == '5873258351'[:9]
assert str(pi)[-10:-1] == '5256375678'[:9]
mp.dps = 15
def test_monitor():
f = lambda x: x**2
a = []
b = []
g = monitor(f, a.append, b.append)
assert g(3) == 9
assert g(4) == 16
assert a[0] == ((3,), {})
assert b[0] == 9
def test_nint_distance():
assert nint_distance(mpf(-3)) == (-3, -inf)
assert nint_distance(mpc(-3)) == (-3, -inf)
assert nint_distance(mpf(-3.1)) == (-3, -3)
assert nint_distance(mpf(-3.01)) == (-3, -6)
assert nint_distance(mpf(-3.001)) == (-3, -9)
assert nint_distance(mpf(-3.0001)) == (-3, -13)
assert nint_distance(mpf(-2.9)) == (-3, -3)
assert nint_distance(mpf(-2.99)) == (-3, -6)
assert nint_distance(mpf(-2.999)) == (-3, -9)
assert nint_distance(mpf(-2.9999)) == (-3, -13)
assert nint_distance(mpc(-3+0.1j)) == (-3, -3)
assert nint_distance(mpc(-3+0.01j)) == (-3, -6)
assert nint_distance(mpc(-3.1+0.1j)) == (-3, -3)
assert nint_distance(mpc(-3.01+0.01j)) == (-3, -6)
assert nint_distance(mpc(-3.001+0.001j)) == (-3, -9)
assert nint_distance(mpf(0)) == (0, -inf)
assert nint_distance(mpf(0.01)) == (0, -6)
assert nint_distance(mpf('1e-100')) == (0, -332)
def test_floor_ceil_nint_frac():
mp.dps = 15
for n in range(-10,10):
assert floor(n) == n
assert floor(n+0.5) == n
assert ceil(n) == n
assert ceil(n+0.5) == n+1
assert nint(n) == n
# nint rounds to even
if n % 2 == 1:
assert nint(n+0.5) == n+1
else:
assert nint(n+0.5) == n
assert floor(inf) == inf
assert floor(ninf) == ninf
assert isnan(floor(nan))
assert ceil(inf) == inf
assert ceil(ninf) == ninf
assert isnan(ceil(nan))
assert nint(inf) == inf
assert nint(ninf) == ninf
assert isnan(nint(nan))
assert floor(0.1) == 0
assert floor(0.9) == 0
assert floor(-0.1) == -1
assert floor(-0.9) == -1
assert floor(10000000000.1) == 10000000000
assert floor(10000000000.9) == 10000000000
assert floor(-10000000000.1) == -10000000000-1
assert floor(-10000000000.9) == -10000000000-1
assert floor(1e-100) == 0
assert floor(-1e-100) == -1
assert floor(1e100) == 1e100
assert floor(-1e100) == -1e100
assert ceil(0.1) == 1
assert ceil(0.9) == 1
assert ceil(-0.1) == 0
assert ceil(-0.9) == 0
assert ceil(10000000000.1) == 10000000000+1
assert ceil(10000000000.9) == 10000000000+1
assert ceil(-10000000000.1) == -10000000000
assert ceil(-10000000000.9) == -10000000000
assert ceil(1e-100) == 1
assert ceil(-1e-100) == 0
assert ceil(1e100) == 1e100
assert ceil(-1e100) == -1e100
assert nint(0.1) == 0
assert nint(0.9) == 1
assert nint(-0.1) == 0
assert nint(-0.9) == -1
assert nint(10000000000.1) == 10000000000
assert nint(10000000000.9) == 10000000000+1
assert nint(-10000000000.1) == -10000000000
assert nint(-10000000000.9) == -10000000000-1
assert nint(1e-100) == 0
assert nint(-1e-100) == 0
assert nint(1e100) == 1e100
assert nint(-1e100) == -1e100
assert floor(3.2+4.6j) == 3+4j
assert ceil(3.2+4.6j) == 4+5j
assert nint(3.2+4.6j) == 3+5j
for n in range(-10,10):
assert frac(n) == 0
assert frac(0.25) == 0.25
assert frac(1.25) == 0.25
assert frac(2.25) == 0.25
assert frac(-0.25) == 0.75
assert frac(-1.25) == 0.75
assert frac(-2.25) == 0.75
assert frac('1e100000000000000') == 0
u = mpf('1e-100000000000000')
assert frac(u) == u
assert frac(-u) == 1 # rounding!
u = mpf('1e-400')
assert frac(-u, prec=0) == fsub(1, u, exact=True)
assert frac(3.25+4.75j) == 0.25+0.75j
def test_isnan_etc():
from mpmath.rational import mpq
assert isnan(nan) == True
assert isnan(3) == False
assert isnan(mpf(3)) == False
assert isnan(inf) == False
assert isnan(mpc(2,nan)) == True
assert isnan(mpc(2,nan)) == True
assert isnan(mpc(nan,nan)) == True
assert isnan(mpc(2,2)) == False
assert isnan(mpc(nan,inf)) == True
assert isnan(mpc(inf,inf)) == False
assert isnan(mpq((3,2))) == False
assert isnan(mpq((0,1))) == False
assert isinf(inf) == True
assert isinf(-inf) == True
assert isinf(3) == False
assert isinf(nan) == False
assert isinf(3+4j) == False
assert isinf(mpc(inf)) == True
assert isinf(mpc(3,inf)) == True
assert isinf(mpc(inf,3)) == True
assert isinf(mpc(inf,inf)) == True
assert isinf(mpc(nan,inf)) == True
assert isinf(mpc(inf,nan)) == True
assert isinf(mpc(nan,nan)) == False
assert isinf(mpq((3,2))) == False
assert isinf(mpq((0,1))) == False
assert isnormal(3) == True
assert isnormal(3.5) == True
assert isnormal(mpf(3.5)) == True
assert isnormal(0) == False
assert isnormal(mpf(0)) == False
assert isnormal(0.0) == False
assert isnormal(inf) == False
assert isnormal(-inf) == False
assert isnormal(nan) == False
assert isnormal(float(inf)) == False
assert isnormal(mpc(0,0)) == False
assert isnormal(mpc(3,0)) == True
assert isnormal(mpc(0,3)) == True
assert isnormal(mpc(3,3)) == True
assert isnormal(mpc(0,nan)) == False
assert isnormal(mpc(0,inf)) == False
assert isnormal(mpc(3,nan)) == False
assert isnormal(mpc(3,inf)) == False
assert isnormal(mpc(3,-inf)) == False
assert isnormal(mpc(nan,0)) == False
assert isnormal(mpc(inf,0)) == False
assert isnormal(mpc(nan,3)) == False
assert isnormal(mpc(inf,3)) == False
assert isnormal(mpc(inf,nan)) == False
assert isnormal(mpc(nan,inf)) == False
assert isnormal(mpc(nan,nan)) == False
assert isnormal(mpc(inf,inf)) == False
assert isnormal(mpq((3,2))) == True
assert isnormal(mpq((0,1))) == False
assert isint(3) == True
assert isint(0) == True
assert isint(long(3)) == True
assert isint(long(0)) == True
assert isint(mpf(3)) == True
assert isint(mpf(0)) == True
assert isint(mpf(-3)) == True
assert isint(mpf(3.2)) == False
assert isint(3.2) == False
assert isint(nan) == False
assert isint(inf) == False
assert isint(-inf) == False
assert isint(mpc(0)) == True
assert isint(mpc(3)) == True
assert isint(mpc(3.2)) == False
assert isint(mpc(3,inf)) == False
assert isint(mpc(inf)) == False
assert isint(mpc(3,2)) == False
assert isint(mpc(0,2)) == False
assert isint(mpc(3,2),gaussian=True) == True
assert isint(mpc(3,0),gaussian=True) == True
assert isint(mpc(0,3),gaussian=True) == True
assert isint(3+4j) == False
assert isint(3+4j, gaussian=True) == True
assert isint(3+0j) == True
assert isint(mpq((3,2))) == False
assert isint(mpq((3,9))) == False
assert isint(mpq((9,3))) == True
assert isint(mpq((0,4))) == True
assert isint(mpq((1,1))) == True
assert isint(mpq((-1,1))) == True
assert mp.isnpint(0) == True
assert mp.isnpint(1) == False
assert mp.isnpint(-1) == True
assert mp.isnpint(-1.1) == False
assert mp.isnpint(-1.0) == True
assert mp.isnpint(mp.mpq(1,2)) == False
assert mp.isnpint(mp.mpq(-1,2)) == False
assert mp.isnpint(mp.mpq(-3,1)) == True
assert mp.isnpint(mp.mpq(0,1)) == True
assert mp.isnpint(mp.mpq(1,1)) == False
assert mp.isnpint(0+0j) == True
assert mp.isnpint(-1+0j) == True
assert mp.isnpint(-1.1+0j) == False
assert mp.isnpint(-1+0.1j) == False
assert mp.isnpint(0+0.1j) == False
def test_issue_438():
assert mpf(finf) == mpf('inf')
assert mpf(fninf) == mpf('-inf')
assert mpf(fnan)._mpf_ == mpf('nan')._mpf_

View File

@ -0,0 +1,188 @@
"""
Test bit-level integer and mpf operations
"""
from mpmath import *
from mpmath.libmp import *
def test_bitcount():
assert bitcount(0) == 0
assert bitcount(1) == 1
assert bitcount(7) == 3
assert bitcount(8) == 4
assert bitcount(2**100) == 101
assert bitcount(2**100-1) == 100
def test_trailing():
assert trailing(0) == 0
assert trailing(1) == 0
assert trailing(2) == 1
assert trailing(7) == 0
assert trailing(8) == 3
assert trailing(2**100) == 100
assert trailing(2**100-1) == 0
def test_round_down():
assert from_man_exp(0, -4, 4, round_down)[:3] == (0, 0, 0)
assert from_man_exp(0xf0, -4, 4, round_down)[:3] == (0, 15, 0)
assert from_man_exp(0xf1, -4, 4, round_down)[:3] == (0, 15, 0)
assert from_man_exp(0xff, -4, 4, round_down)[:3] == (0, 15, 0)
assert from_man_exp(-0xf0, -4, 4, round_down)[:3] == (1, 15, 0)
assert from_man_exp(-0xf1, -4, 4, round_down)[:3] == (1, 15, 0)
assert from_man_exp(-0xff, -4, 4, round_down)[:3] == (1, 15, 0)
def test_round_up():
assert from_man_exp(0, -4, 4, round_up)[:3] == (0, 0, 0)
assert from_man_exp(0xf0, -4, 4, round_up)[:3] == (0, 15, 0)
assert from_man_exp(0xf1, -4, 4, round_up)[:3] == (0, 1, 4)
assert from_man_exp(0xff, -4, 4, round_up)[:3] == (0, 1, 4)
assert from_man_exp(-0xf0, -4, 4, round_up)[:3] == (1, 15, 0)
assert from_man_exp(-0xf1, -4, 4, round_up)[:3] == (1, 1, 4)
assert from_man_exp(-0xff, -4, 4, round_up)[:3] == (1, 1, 4)
def test_round_floor():
assert from_man_exp(0, -4, 4, round_floor)[:3] == (0, 0, 0)
assert from_man_exp(0xf0, -4, 4, round_floor)[:3] == (0, 15, 0)
assert from_man_exp(0xf1, -4, 4, round_floor)[:3] == (0, 15, 0)
assert from_man_exp(0xff, -4, 4, round_floor)[:3] == (0, 15, 0)
assert from_man_exp(-0xf0, -4, 4, round_floor)[:3] == (1, 15, 0)
assert from_man_exp(-0xf1, -4, 4, round_floor)[:3] == (1, 1, 4)
assert from_man_exp(-0xff, -4, 4, round_floor)[:3] == (1, 1, 4)
def test_round_ceiling():
assert from_man_exp(0, -4, 4, round_ceiling)[:3] == (0, 0, 0)
assert from_man_exp(0xf0, -4, 4, round_ceiling)[:3] == (0, 15, 0)
assert from_man_exp(0xf1, -4, 4, round_ceiling)[:3] == (0, 1, 4)
assert from_man_exp(0xff, -4, 4, round_ceiling)[:3] == (0, 1, 4)
assert from_man_exp(-0xf0, -4, 4, round_ceiling)[:3] == (1, 15, 0)
assert from_man_exp(-0xf1, -4, 4, round_ceiling)[:3] == (1, 15, 0)
assert from_man_exp(-0xff, -4, 4, round_ceiling)[:3] == (1, 15, 0)
def test_round_nearest():
assert from_man_exp(0, -4, 4, round_nearest)[:3] == (0, 0, 0)
assert from_man_exp(0xf0, -4, 4, round_nearest)[:3] == (0, 15, 0)
assert from_man_exp(0xf7, -4, 4, round_nearest)[:3] == (0, 15, 0)
assert from_man_exp(0xf8, -4, 4, round_nearest)[:3] == (0, 1, 4) # 1111.1000 -> 10000.0
assert from_man_exp(0xf9, -4, 4, round_nearest)[:3] == (0, 1, 4) # 1111.1001 -> 10000.0
assert from_man_exp(0xe8, -4, 4, round_nearest)[:3] == (0, 7, 1) # 1110.1000 -> 1110.0
assert from_man_exp(0xe9, -4, 4, round_nearest)[:3] == (0, 15, 0) # 1110.1001 -> 1111.0
assert from_man_exp(-0xf0, -4, 4, round_nearest)[:3] == (1, 15, 0)
assert from_man_exp(-0xf7, -4, 4, round_nearest)[:3] == (1, 15, 0)
assert from_man_exp(-0xf8, -4, 4, round_nearest)[:3] == (1, 1, 4)
assert from_man_exp(-0xf9, -4, 4, round_nearest)[:3] == (1, 1, 4)
assert from_man_exp(-0xe8, -4, 4, round_nearest)[:3] == (1, 7, 1)
assert from_man_exp(-0xe9, -4, 4, round_nearest)[:3] == (1, 15, 0)
def test_rounding_bugs():
# 1 less than power-of-two cases
assert from_man_exp(72057594037927935, -56, 53, round_up) == (0, 1, 0, 1)
assert from_man_exp(73786976294838205979, -65, 53, round_nearest) == (0, 1, 1, 1)
assert from_man_exp(31, 0, 4, round_up) == (0, 1, 5, 1)
assert from_man_exp(-31, 0, 4, round_floor) == (1, 1, 5, 1)
assert from_man_exp(255, 0, 7, round_up) == (0, 1, 8, 1)
assert from_man_exp(-255, 0, 7, round_floor) == (1, 1, 8, 1)
def test_rounding_issue_200():
a = from_man_exp(9867,-100)
b = from_man_exp(9867,-200)
c = from_man_exp(-1,0)
z = (1, 1023, -10, 10)
assert mpf_add(a, c, 10, 'd') == z
assert mpf_add(b, c, 10, 'd') == z
assert mpf_add(c, a, 10, 'd') == z
assert mpf_add(c, b, 10, 'd') == z
def test_perturb():
a = fone
b = from_float(0.99999999999999989)
c = from_float(1.0000000000000002)
assert mpf_perturb(a, 0, 53, round_nearest) == a
assert mpf_perturb(a, 1, 53, round_nearest) == a
assert mpf_perturb(a, 0, 53, round_up) == c
assert mpf_perturb(a, 0, 53, round_ceiling) == c
assert mpf_perturb(a, 0, 53, round_down) == a
assert mpf_perturb(a, 0, 53, round_floor) == a
assert mpf_perturb(a, 1, 53, round_up) == a
assert mpf_perturb(a, 1, 53, round_ceiling) == a
assert mpf_perturb(a, 1, 53, round_down) == b
assert mpf_perturb(a, 1, 53, round_floor) == b
a = mpf_neg(a)
b = mpf_neg(b)
c = mpf_neg(c)
assert mpf_perturb(a, 0, 53, round_nearest) == a
assert mpf_perturb(a, 1, 53, round_nearest) == a
assert mpf_perturb(a, 0, 53, round_up) == a
assert mpf_perturb(a, 0, 53, round_floor) == a
assert mpf_perturb(a, 0, 53, round_down) == b
assert mpf_perturb(a, 0, 53, round_ceiling) == b
assert mpf_perturb(a, 1, 53, round_up) == c
assert mpf_perturb(a, 1, 53, round_floor) == c
assert mpf_perturb(a, 1, 53, round_down) == a
assert mpf_perturb(a, 1, 53, round_ceiling) == a
def test_add_exact():
ff = from_float
assert mpf_add(ff(3.0), ff(2.5)) == ff(5.5)
assert mpf_add(ff(3.0), ff(-2.5)) == ff(0.5)
assert mpf_add(ff(-3.0), ff(2.5)) == ff(-0.5)
assert mpf_add(ff(-3.0), ff(-2.5)) == ff(-5.5)
assert mpf_sub(mpf_add(fone, ff(1e-100)), fone) == ff(1e-100)
assert mpf_sub(mpf_add(ff(1e-100), fone), fone) == ff(1e-100)
assert mpf_sub(mpf_add(fone, ff(-1e-100)), fone) == ff(-1e-100)
assert mpf_sub(mpf_add(ff(-1e-100), fone), fone) == ff(-1e-100)
assert mpf_add(fone, fzero) == fone
assert mpf_add(fzero, fone) == fone
assert mpf_add(fzero, fzero) == fzero
def test_long_exponent_shifts():
mp.dps = 15
# Check for possible bugs due to exponent arithmetic overflow
# in a C implementation
x = mpf(1)
for p in [32, 64]:
a = ldexp(1,2**(p-1))
b = ldexp(1,2**p)
c = ldexp(1,2**(p+1))
d = ldexp(1,-2**(p-1))
e = ldexp(1,-2**p)
f = ldexp(1,-2**(p+1))
assert (x+a) == a
assert (x+b) == b
assert (x+c) == c
assert (x+d) == x
assert (x+e) == x
assert (x+f) == x
assert (a+x) == a
assert (b+x) == b
assert (c+x) == c
assert (d+x) == x
assert (e+x) == x
assert (f+x) == x
assert (x-a) == -a
assert (x-b) == -b
assert (x-c) == -c
assert (x-d) == x
assert (x-e) == x
assert (x-f) == x
assert (a-x) == a
assert (b-x) == b
assert (c-x) == c
assert (d-x) == -x
assert (e-x) == -x
assert (f-x) == -x
def test_float_rounding():
mp.prec = 64
for x in [mpf(1), mpf(1)+eps, mpf(1)-eps, -mpf(1)+eps, -mpf(1)-eps]:
fa = float(x)
fb = float(fadd(x,0,prec=53,rounding='n'))
assert fa == fb
z = mpc(x,x)
ca = complex(z)
cb = complex(fadd(z,0,prec=53,rounding='n'))
assert ca == cb
for rnd in ['n', 'd', 'u', 'f', 'c']:
fa = to_float(x._mpf_, rnd=rnd)
fb = to_float(fadd(x,0,prec=53,rounding=rnd)._mpf_, rnd=rnd)
assert fa == fb
mp.prec = 53

View File

@ -0,0 +1,216 @@
import pytest
from mpmath import *
def test_approximation():
mp.dps = 15
f = lambda x: cos(2-2*x)/x
p, err = chebyfit(f, [2, 4], 8, error=True)
assert err < 1e-5
for i in range(10):
x = 2 + i/5.
assert abs(polyval(p, x) - f(x)) < err
def test_limits():
mp.dps = 15
assert limit(lambda x: (x-sin(x))/x**3, 0).ae(mpf(1)/6)
assert limit(lambda n: (1+1/n)**n, inf).ae(e)
def test_polyval():
assert polyval([], 3) == 0
assert polyval([0], 3) == 0
assert polyval([5], 3) == 5
# 4x^3 - 2x + 5
p = [4, 0, -2, 5]
assert polyval(p,4) == 253
assert polyval(p,4,derivative=True) == (253, 190)
def test_polyroots():
p = polyroots([1,-4])
assert p[0].ae(4)
p, q = polyroots([1,2,3])
assert p.ae(-1 - sqrt(2)*j)
assert q.ae(-1 + sqrt(2)*j)
#this is not a real test, it only tests a specific case
assert polyroots([1]) == []
pytest.raises(ValueError, lambda: polyroots([0]))
def test_polyroots_legendre():
n = 64
coeffs = [11975573020964041433067793888190275875, 0,
-190100434726484311252477736051902332000, 0,
1437919688271127330313741595496589239248, 0,
-6897338342113537600691931230430793911840, 0,
23556405536185284408974715545252277554280, 0,
-60969520211303089058522793175947071316960, 0,
124284021969194758465450309166353645376880, 0,
-204721258548015217049921875719981284186016, 0,
277415422258095841688223780704620656114900, 0,
-313237834141273382807123548182995095192800, 0,
297432255354328395601259515935229287637200, 0,
-239057700565161140389797367947941296605600, 0,
163356095386193445933028201431093219347160, 0,
-95158890516229191805647495979277603503200, 0,
47310254620162038075933656063247634556400, 0,
-20071017111583894941305187420771723751200, 0,
7255051932731034189479516844750603752850, 0,
-2228176940331017311443863996901733412640, 0,
579006552594977616773047095969088431600, 0,
-126584428502545713788439446082310831200, 0,
23112325428835593809686977515028663000, 0,
-3491517141958743235617737161547844000, 0,
431305058712550634988073414073557200, 0,
-42927166660756742088912492757452000, 0,
3378527005707706553294038781836500, 0,
-205277590220215081719131470288800, 0,
9330799555464321896324157740400, 0,
-304114948474392713657972548576, 0,
6695289961520387531608984680, 0,
-91048139350447232095702560, 0,
659769125727878493447120, 0,
-1905929106580294155360, 0,
916312070471295267]
with mp.workdps(3):
with pytest.raises(mp.NoConvergence):
polyroots(coeffs, maxsteps=5, cleanup=True, error=False,
extraprec=n*10)
roots = polyroots(coeffs, maxsteps=50, cleanup=True, error=False,
extraprec=n*10)
roots = [str(r) for r in roots]
assert roots == \
['-0.999', '-0.996', '-0.991', '-0.983', '-0.973', '-0.961',
'-0.946', '-0.93', '-0.911', '-0.889', '-0.866', '-0.841',
'-0.813', '-0.784', '-0.753', '-0.72', '-0.685', '-0.649',
'-0.611', '-0.572', '-0.531', '-0.489', '-0.446', '-0.402',
'-0.357', '-0.311', '-0.265', '-0.217', '-0.17', '-0.121',
'-0.073', '-0.0243', '0.0243', '0.073', '0.121', '0.17', '0.217',
'0.265', '0.311', '0.357', '0.402', '0.446', '0.489', '0.531',
'0.572', '0.611', '0.649', '0.685', '0.72', '0.753', '0.784',
'0.813', '0.841', '0.866', '0.889', '0.911', '0.93', '0.946',
'0.961', '0.973', '0.983', '0.991', '0.996', '0.999']
def test_polyroots_legendre_init():
extra_prec = 100
coeffs = [11975573020964041433067793888190275875, 0,
-190100434726484311252477736051902332000, 0,
1437919688271127330313741595496589239248, 0,
-6897338342113537600691931230430793911840, 0,
23556405536185284408974715545252277554280, 0,
-60969520211303089058522793175947071316960, 0,
124284021969194758465450309166353645376880, 0,
-204721258548015217049921875719981284186016, 0,
277415422258095841688223780704620656114900, 0,
-313237834141273382807123548182995095192800, 0,
297432255354328395601259515935229287637200, 0,
-239057700565161140389797367947941296605600, 0,
163356095386193445933028201431093219347160, 0,
-95158890516229191805647495979277603503200, 0,
47310254620162038075933656063247634556400, 0,
-20071017111583894941305187420771723751200, 0,
7255051932731034189479516844750603752850, 0,
-2228176940331017311443863996901733412640, 0,
579006552594977616773047095969088431600, 0,
-126584428502545713788439446082310831200, 0,
23112325428835593809686977515028663000, 0,
-3491517141958743235617737161547844000, 0,
431305058712550634988073414073557200, 0,
-42927166660756742088912492757452000, 0,
3378527005707706553294038781836500, 0,
-205277590220215081719131470288800, 0,
9330799555464321896324157740400, 0,
-304114948474392713657972548576, 0,
6695289961520387531608984680, 0,
-91048139350447232095702560, 0,
659769125727878493447120, 0,
-1905929106580294155360, 0,
916312070471295267]
roots_init = matrix(['-0.999', '-0.996', '-0.991', '-0.983', '-0.973',
'-0.961', '-0.946', '-0.93', '-0.911', '-0.889',
'-0.866', '-0.841', '-0.813', '-0.784', '-0.753',
'-0.72', '-0.685', '-0.649', '-0.611', '-0.572',
'-0.531', '-0.489', '-0.446', '-0.402', '-0.357',
'-0.311', '-0.265', '-0.217', '-0.17', '-0.121',
'-0.073', '-0.0243', '0.0243', '0.073', '0.121',
'0.17', '0.217', '0.265', ' 0.311', '0.357',
'0.402', '0.446', '0.489', '0.531', '0.572',
'0.611', '0.649', '0.685', '0.72', '0.753',
'0.784', '0.813', '0.841', '0.866', '0.889',
'0.911', '0.93', '0.946', '0.961', '0.973',
'0.983', '0.991', '0.996', '0.999', '1.0'])
with mp.workdps(2*mp.dps):
roots_exact = polyroots(coeffs, maxsteps=50, cleanup=True, error=False,
extraprec=2*extra_prec)
with pytest.raises(mp.NoConvergence):
polyroots(coeffs, maxsteps=5, cleanup=True, error=False,
extraprec=extra_prec)
roots,err = polyroots(coeffs, maxsteps=5, cleanup=True, error=True,
extraprec=extra_prec,roots_init=roots_init)
assert max(matrix(roots_exact)-matrix(roots).apply(abs)) < err
roots1,err1 = polyroots(coeffs, maxsteps=25, cleanup=True, error=True,
extraprec=extra_prec,roots_init=roots_init[:60])
assert max(matrix(roots_exact)-matrix(roots1).apply(abs)) < err1
def test_pade():
one = mpf(1)
mp.dps = 20
N = 10
a = [one]
k = 1
for i in range(1, N+1):
k *= i
a.append(one/k)
p, q = pade(a, N//2, N//2)
for x in arange(0, 1, 0.1):
r = polyval(p[::-1], x)/polyval(q[::-1], x)
assert(r.ae(exp(x), 1.0e-10))
mp.dps = 15
def test_fourier():
mp.dps = 15
c, s = fourier(lambda x: x+1, [-1, 2], 2)
#plot([lambda x: x+1, lambda x: fourierval((c, s), [-1, 2], x)], [-1, 2])
assert c[0].ae(1.5)
assert c[1].ae(-3*sqrt(3)/(2*pi))
assert c[2].ae(3*sqrt(3)/(4*pi))
assert s[0] == 0
assert s[1].ae(3/(2*pi))
assert s[2].ae(3/(4*pi))
assert fourierval((c, s), [-1, 2], 1).ae(1.9134966715663442)
def test_differint():
mp.dps = 15
assert differint(lambda t: t, 2, -0.5).ae(8*sqrt(2/pi)/3)
def test_invlap():
mp.dps = 15
t = 0.01
fp = lambda p: 1/(p+1)**2
ft = lambda t: t*exp(-t)
ftt = ft(t)
assert invertlaplace(fp,t,method='talbot').ae(ftt)
assert invertlaplace(fp,t,method='stehfest').ae(ftt)
assert invertlaplace(fp,t,method='dehoog').ae(ftt)
assert invertlaplace(fp,t,method='cohen').ae(ftt)
t = 1.0
ftt = ft(t)
assert invertlaplace(fp,t,method='talbot').ae(ftt)
assert invertlaplace(fp,t,method='stehfest').ae(ftt)
assert invertlaplace(fp,t,method='dehoog').ae(ftt)
assert invertlaplace(fp,t,method='cohen').ae(ftt)
t = 0.01
fp = lambda p: log(p)/p
ft = lambda t: -euler-log(t)
ftt = ft(t)
assert invertlaplace(fp,t,method='talbot').ae(ftt)
assert invertlaplace(fp,t,method='stehfest').ae(ftt)
assert invertlaplace(fp,t,method='dehoog').ae(ftt)
assert invertlaplace(fp,t,method='cohen').ae(ftt)
t = 1.0
ftt = ft(t)
assert invertlaplace(fp,t,method='talbot').ae(ftt)
assert invertlaplace(fp,t,method='stehfest').ae(ftt)
assert invertlaplace(fp,t,method='dehoog').ae(ftt)
assert invertlaplace(fp,t,method='cohen').ae(ftt)

View File

@ -0,0 +1,77 @@
from mpmath import *
from random import seed, randint, random
import math
# Test compatibility with Python floats, which are
# IEEE doubles (53-bit)
N = 5000
seed(1)
# Choosing exponents between roughly -140, 140 ensures that
# the Python floats don't overflow or underflow
xs = [(random()-1) * 10**randint(-140, 140) for x in range(N)]
ys = [(random()-1) * 10**randint(-140, 140) for x in range(N)]
# include some equal values
ys[int(N*0.8):] = xs[int(N*0.8):]
# Detect whether Python is compiled to use 80-bit floating-point
# instructions, in which case the double compatibility test breaks
uses_x87 = -4.1974624032366689e+117 / -8.4657370748010221e-47 \
== 4.9581771393902231e+163
def test_double_compatibility():
mp.prec = 53
for x, y in zip(xs, ys):
mpx = mpf(x)
mpy = mpf(y)
assert mpf(x) == x
assert (mpx < mpy) == (x < y)
assert (mpx > mpy) == (x > y)
assert (mpx == mpy) == (x == y)
assert (mpx != mpy) == (x != y)
assert (mpx <= mpy) == (x <= y)
assert (mpx >= mpy) == (x >= y)
assert mpx == mpx
if uses_x87:
mp.prec = 64
a = mpx + mpy
b = mpx * mpy
c = mpx / mpy
d = mpx % mpy
mp.prec = 53
assert +a == x + y
assert +b == x * y
assert +c == x / y
assert +d == x % y
else:
assert mpx + mpy == x + y
assert mpx * mpy == x * y
assert mpx / mpy == x / y
assert mpx % mpy == x % y
assert abs(mpx) == abs(x)
assert mpf(repr(x)) == x
assert ceil(mpx) == math.ceil(x)
assert floor(mpx) == math.floor(x)
def test_sqrt():
# this fails quite often. it appers to be float
# that rounds the wrong way, not mpf
fail = 0
mp.prec = 53
for x in xs:
x = abs(x)
mp.prec = 100
mp_high = mpf(x)**0.5
mp.prec = 53
mp_low = mpf(x)**0.5
fp = x**0.5
assert abs(mp_low-mp_high) <= abs(fp-mp_high)
fail += mp_low != fp
assert fail < N/10
def test_bugs():
# particular bugs
assert mpf(4.4408920985006262E-16) < mpf(1.7763568394002505E-15)
assert mpf(-4.4408920985006262E-16) > mpf(-1.7763568394002505E-15)

View File

@ -0,0 +1,233 @@
import random
from mpmath import *
from mpmath.libmp import *
def test_basic_string():
"""
Test basic string conversion
"""
mp.dps = 15
assert mpf('3') == mpf('3.0') == mpf('0003.') == mpf('0.03e2') == mpf(3.0)
assert mpf('30') == mpf('30.0') == mpf('00030.') == mpf(30.0)
for i in range(10):
for j in range(10):
assert mpf('%ie%i' % (i,j)) == i * 10**j
assert str(mpf('25000.0')) == '25000.0'
assert str(mpf('2500.0')) == '2500.0'
assert str(mpf('250.0')) == '250.0'
assert str(mpf('25.0')) == '25.0'
assert str(mpf('2.5')) == '2.5'
assert str(mpf('0.25')) == '0.25'
assert str(mpf('0.025')) == '0.025'
assert str(mpf('0.0025')) == '0.0025'
assert str(mpf('0.00025')) == '0.00025'
assert str(mpf('0.000025')) == '2.5e-5'
assert str(mpf(0)) == '0.0'
assert str(mpf('2.5e1000000000000000000000')) == '2.5e+1000000000000000000000'
assert str(mpf('2.6e-1000000000000000000000')) == '2.6e-1000000000000000000000'
assert str(mpf(1.23402834e-15)) == '1.23402834e-15'
assert str(mpf(-1.23402834e-15)) == '-1.23402834e-15'
assert str(mpf(-1.2344e-15)) == '-1.2344e-15'
assert repr(mpf(-1.2344e-15)) == "mpf('-1.2343999999999999e-15')"
assert str(mpf("2163048125L")) == '2163048125.0'
assert str(mpf("-2163048125l")) == '-2163048125.0'
assert str(mpf("-2163048125L/1088391168")) == '-1.98738118113799'
assert str(mpf("2163048125/1088391168l")) == '1.98738118113799'
def test_pretty():
mp.pretty = True
assert repr(mpf(2.5)) == '2.5'
assert repr(mpc(2.5,3.5)) == '(2.5 + 3.5j)'
mp.pretty = False
iv.pretty = True
assert repr(mpi(2.5,3.5)) == '[2.5, 3.5]'
iv.pretty = False
def test_str_whitespace():
assert mpf('1.26 ') == 1.26
def test_unicode():
mp.dps = 15
try:
unicode = unicode
except NameError:
unicode = str
assert mpf(unicode('2.76')) == 2.76
assert mpf(unicode('inf')) == inf
def test_str_format():
assert to_str(from_float(0.1),15,strip_zeros=False) == '0.100000000000000'
assert to_str(from_float(0.0),15,show_zero_exponent=True) == '0.0e+0'
assert to_str(from_float(0.0),0,show_zero_exponent=True) == '.0e+0'
assert to_str(from_float(0.0),0,show_zero_exponent=False) == '.0'
assert to_str(from_float(0.0),1,show_zero_exponent=True) == '0.0e+0'
assert to_str(from_float(0.0),1,show_zero_exponent=False) == '0.0'
assert to_str(from_float(1.23),3,show_zero_exponent=True) == '1.23e+0'
assert to_str(from_float(1.23456789000000e-2),15,strip_zeros=False,min_fixed=0,max_fixed=0) == '1.23456789000000e-2'
assert to_str(from_float(1.23456789000000e+2),15,strip_zeros=False,min_fixed=0,max_fixed=0) == '1.23456789000000e+2'
assert to_str(from_float(2.1287e14), 15, max_fixed=1000) == '212870000000000.0'
assert to_str(from_float(2.1287e15), 15, max_fixed=1000) == '2128700000000000.0'
assert to_str(from_float(2.1287e16), 15, max_fixed=1000) == '21287000000000000.0'
assert to_str(from_float(2.1287e30), 15, max_fixed=1000) == '2128700000000000000000000000000.0'
def test_tight_string_conversion():
mp.dps = 15
# In an old version, '0.5' wasn't recognized as representing
# an exact binary number and was erroneously rounded up or down
assert from_str('0.5', 10, round_floor) == fhalf
assert from_str('0.5', 10, round_ceiling) == fhalf
def test_eval_repr_invariant():
"""Test that eval(repr(x)) == x"""
random.seed(123)
for dps in [10, 15, 20, 50, 100]:
mp.dps = dps
for i in range(1000):
a = mpf(random.random())**0.5 * 10**random.randint(-100, 100)
assert eval(repr(a)) == a
mp.dps = 15
def test_str_bugs():
mp.dps = 15
# Decimal rounding used to give the wrong exponent in some cases
assert str(mpf('1e600')) == '1.0e+600'
assert str(mpf('1e10000')) == '1.0e+10000'
def test_str_prec0():
assert to_str(from_float(1.234), 0) == '.0e+0'
assert to_str(from_float(1e-15), 0) == '.0e-15'
assert to_str(from_float(1e+15), 0) == '.0e+15'
assert to_str(from_float(-1e-15), 0) == '-.0e-15'
assert to_str(from_float(-1e+15), 0) == '-.0e+15'
def test_convert_rational():
mp.dps = 15
assert from_rational(30, 5, 53, round_nearest) == (0, 3, 1, 2)
assert from_rational(-7, 4, 53, round_nearest) == (1, 7, -2, 3)
assert to_rational((0, 1, -1, 1)) == (1, 2)
def test_custom_class():
class mympf:
@property
def _mpf_(self):
return mpf(3.5)._mpf_
class mympc:
@property
def _mpc_(self):
return mpf(3.5)._mpf_, mpf(2.5)._mpf_
assert mpf(2) + mympf() == 5.5
assert mympf() + mpf(2) == 5.5
assert mpf(mympf()) == 3.5
assert mympc() + mpc(2) == mpc(5.5, 2.5)
assert mpc(2) + mympc() == mpc(5.5, 2.5)
assert mpc(mympc()) == (3.5+2.5j)
def test_conversion_methods():
class SomethingRandom:
pass
class SomethingReal:
def _mpmath_(self, prec, rounding):
return mp.make_mpf(from_str('1.3', prec, rounding))
class SomethingComplex:
def _mpmath_(self, prec, rounding):
return mp.make_mpc((from_str('1.3', prec, rounding), \
from_str('1.7', prec, rounding)))
x = mpf(3)
z = mpc(3)
a = SomethingRandom()
y = SomethingReal()
w = SomethingComplex()
for d in [15, 45]:
mp.dps = d
assert (x+y).ae(mpf('4.3'))
assert (y+x).ae(mpf('4.3'))
assert (x+w).ae(mpc('4.3', '1.7'))
assert (w+x).ae(mpc('4.3', '1.7'))
assert (z+y).ae(mpc('4.3'))
assert (y+z).ae(mpc('4.3'))
assert (z+w).ae(mpc('4.3', '1.7'))
assert (w+z).ae(mpc('4.3', '1.7'))
x-y; y-x; x-w; w-x; z-y; y-z; z-w; w-z
x*y; y*x; x*w; w*x; z*y; y*z; z*w; w*z
x/y; y/x; x/w; w/x; z/y; y/z; z/w; w/z
x**y; y**x; x**w; w**x; z**y; y**z; z**w; w**z
x==y; y==x; x==w; w==x; z==y; y==z; z==w; w==z
mp.dps = 15
assert x.__add__(a) is NotImplemented
assert x.__radd__(a) is NotImplemented
assert x.__lt__(a) is NotImplemented
assert x.__gt__(a) is NotImplemented
assert x.__le__(a) is NotImplemented
assert x.__ge__(a) is NotImplemented
assert x.__eq__(a) is NotImplemented
assert x.__ne__(a) is NotImplemented
# implementation detail
if hasattr(x, "__cmp__"):
assert x.__cmp__(a) is NotImplemented
assert x.__sub__(a) is NotImplemented
assert x.__rsub__(a) is NotImplemented
assert x.__mul__(a) is NotImplemented
assert x.__rmul__(a) is NotImplemented
assert x.__div__(a) is NotImplemented
assert x.__rdiv__(a) is NotImplemented
assert x.__mod__(a) is NotImplemented
assert x.__rmod__(a) is NotImplemented
assert x.__pow__(a) is NotImplemented
assert x.__rpow__(a) is NotImplemented
assert z.__add__(a) is NotImplemented
assert z.__radd__(a) is NotImplemented
assert z.__eq__(a) is NotImplemented
assert z.__ne__(a) is NotImplemented
assert z.__sub__(a) is NotImplemented
assert z.__rsub__(a) is NotImplemented
assert z.__mul__(a) is NotImplemented
assert z.__rmul__(a) is NotImplemented
assert z.__div__(a) is NotImplemented
assert z.__rdiv__(a) is NotImplemented
assert z.__pow__(a) is NotImplemented
assert z.__rpow__(a) is NotImplemented
def test_mpmathify():
assert mpmathify('1/2') == 0.5
assert mpmathify('(1.0+1.0j)') == mpc(1, 1)
assert mpmathify('(1.2e-10 - 3.4e5j)') == mpc('1.2e-10', '-3.4e5')
assert mpmathify('1j') == mpc(1j)
def test_issue548():
try:
# This expression is invalid, but may trigger the ReDOS vulnerability
# in the regular expression for parsing complex numbers.
mpmathify('(' + '1' * 5000 + '!j')
except:
return
# The expression is invalid and should raise an exception.
assert False
def test_compatibility():
try:
import numpy as np
from fractions import Fraction
from decimal import Decimal
import decimal
except ImportError:
return
# numpy types
for nptype in np.core.numerictypes.typeDict.values():
if issubclass(nptype, np.complexfloating):
x = nptype(complex(0.5, -0.5))
elif issubclass(nptype, np.floating):
x = nptype(0.5)
elif issubclass(nptype, np.integer):
x = nptype(2)
# Handle the weird types
try: diff = np.abs(type(np.sqrt(x))(sqrt(x)) - np.sqrt(x))
except: continue
assert diff < 2.0**-53
#Fraction and Decimal
oldprec = mp.prec
mp.prec = 1000
decimal.getcontext().prec = mp.dps
assert sqrt(Fraction(2, 3)).ae(sqrt(mpf('2/3')))
assert sqrt(Decimal(2)/Decimal(3)).ae(sqrt(mpf('2/3')))
mp.prec = oldprec

View File

@ -0,0 +1,61 @@
from mpmath import *
def test_diff():
mp.dps = 15
assert diff(log, 2.0, n=0).ae(log(2))
assert diff(cos, 1.0).ae(-sin(1))
assert diff(abs, 0.0) == 0
assert diff(abs, 0.0, direction=1) == 1
assert diff(abs, 0.0, direction=-1) == -1
assert diff(exp, 1.0).ae(e)
assert diff(exp, 1.0, n=5).ae(e)
assert diff(exp, 2.0, n=5, direction=3*j).ae(e**2)
assert diff(lambda x: x**2, 3.0, method='quad').ae(6)
assert diff(lambda x: 3+x**5, 3.0, n=2, method='quad').ae(540)
assert diff(lambda x: 3+x**5, 3.0, n=2, method='step').ae(540)
assert diffun(sin)(2).ae(cos(2))
assert diffun(sin, n=2)(2).ae(-sin(2))
def test_diffs():
mp.dps = 15
assert [chop(d) for d in diffs(sin, 0, 1)] == [0, 1]
assert [chop(d) for d in diffs(sin, 0, 1, method='quad')] == [0, 1]
assert [chop(d) for d in diffs(sin, 0, 2)] == [0, 1, 0]
assert [chop(d) for d in diffs(sin, 0, 2, method='quad')] == [0, 1, 0]
def test_taylor():
mp.dps = 15
# Easy to test since the coefficients are exact in floating-point
assert taylor(sqrt, 1, 4) == [1, 0.5, -0.125, 0.0625, -0.0390625]
def test_diff_partial():
mp.dps = 15
x,y,z = xyz = 2,3,7
f = lambda x,y,z: 3*x**2 * (y+2)**3 * z**5
assert diff(f, xyz, (0,0,0)).ae(25210500)
assert diff(f, xyz, (0,0,1)).ae(18007500)
assert diff(f, xyz, (0,0,2)).ae(10290000)
assert diff(f, xyz, (0,1,0)).ae(15126300)
assert diff(f, xyz, (0,1,1)).ae(10804500)
assert diff(f, xyz, (0,1,2)).ae(6174000)
assert diff(f, xyz, (0,2,0)).ae(6050520)
assert diff(f, xyz, (0,2,1)).ae(4321800)
assert diff(f, xyz, (0,2,2)).ae(2469600)
assert diff(f, xyz, (1,0,0)).ae(25210500)
assert diff(f, xyz, (1,0,1)).ae(18007500)
assert diff(f, xyz, (1,0,2)).ae(10290000)
assert diff(f, xyz, (1,1,0)).ae(15126300)
assert diff(f, xyz, (1,1,1)).ae(10804500)
assert diff(f, xyz, (1,1,2)).ae(6174000)
assert diff(f, xyz, (1,2,0)).ae(6050520)
assert diff(f, xyz, (1,2,1)).ae(4321800)
assert diff(f, xyz, (1,2,2)).ae(2469600)
assert diff(f, xyz, (2,0,0)).ae(12605250)
assert diff(f, xyz, (2,0,1)).ae(9003750)
assert diff(f, xyz, (2,0,2)).ae(5145000)
assert diff(f, xyz, (2,1,0)).ae(7563150)
assert diff(f, xyz, (2,1,1)).ae(5402250)
assert diff(f, xyz, (2,1,2)).ae(3087000)
assert diff(f, xyz, (2,2,0)).ae(3025260)
assert diff(f, xyz, (2,2,1)).ae(2160900)
assert diff(f, xyz, (2,2,2)).ae(1234800)

View File

@ -0,0 +1,143 @@
from mpmath.libmp import *
from mpmath import mpf, mp
from random import randint, choice, seed
all_modes = [round_floor, round_ceiling, round_down, round_up, round_nearest]
fb = from_bstr
fi = from_int
ff = from_float
def test_div_1_3():
a = fi(1)
b = fi(3)
c = fi(-1)
# floor rounds down, ceiling rounds up
assert mpf_div(a, b, 7, round_floor) == fb('0.01010101')
assert mpf_div(a, b, 7, round_ceiling) == fb('0.01010110')
assert mpf_div(a, b, 7, round_down) == fb('0.01010101')
assert mpf_div(a, b, 7, round_up) == fb('0.01010110')
assert mpf_div(a, b, 7, round_nearest) == fb('0.01010101')
# floor rounds up, ceiling rounds down
assert mpf_div(c, b, 7, round_floor) == fb('-0.01010110')
assert mpf_div(c, b, 7, round_ceiling) == fb('-0.01010101')
assert mpf_div(c, b, 7, round_down) == fb('-0.01010101')
assert mpf_div(c, b, 7, round_up) == fb('-0.01010110')
assert mpf_div(c, b, 7, round_nearest) == fb('-0.01010101')
def test_mpf_divi_1_3():
a = 1
b = fi(3)
c = -1
assert mpf_rdiv_int(a, b, 7, round_floor) == fb('0.01010101')
assert mpf_rdiv_int(a, b, 7, round_ceiling) == fb('0.01010110')
assert mpf_rdiv_int(a, b, 7, round_down) == fb('0.01010101')
assert mpf_rdiv_int(a, b, 7, round_up) == fb('0.01010110')
assert mpf_rdiv_int(a, b, 7, round_nearest) == fb('0.01010101')
assert mpf_rdiv_int(c, b, 7, round_floor) == fb('-0.01010110')
assert mpf_rdiv_int(c, b, 7, round_ceiling) == fb('-0.01010101')
assert mpf_rdiv_int(c, b, 7, round_down) == fb('-0.01010101')
assert mpf_rdiv_int(c, b, 7, round_up) == fb('-0.01010110')
assert mpf_rdiv_int(c, b, 7, round_nearest) == fb('-0.01010101')
def test_div_300():
q = fi(1000000)
a = fi(300499999) # a/q is a little less than a half-integer
b = fi(300500000) # b/q exactly a half-integer
c = fi(300500001) # c/q is a little more than a half-integer
# Check nearest integer rounding (prec=9 as 2**8 < 300 < 2**9)
assert mpf_div(a, q, 9, round_down) == fi(300)
assert mpf_div(b, q, 9, round_down) == fi(300)
assert mpf_div(c, q, 9, round_down) == fi(300)
assert mpf_div(a, q, 9, round_up) == fi(301)
assert mpf_div(b, q, 9, round_up) == fi(301)
assert mpf_div(c, q, 9, round_up) == fi(301)
# Nearest even integer is down
assert mpf_div(a, q, 9, round_nearest) == fi(300)
assert mpf_div(b, q, 9, round_nearest) == fi(300)
assert mpf_div(c, q, 9, round_nearest) == fi(301)
# Nearest even integer is up
a = fi(301499999)
b = fi(301500000)
c = fi(301500001)
assert mpf_div(a, q, 9, round_nearest) == fi(301)
assert mpf_div(b, q, 9, round_nearest) == fi(302)
assert mpf_div(c, q, 9, round_nearest) == fi(302)
def test_tight_integer_division():
# Test that integer division at tightest possible precision is exact
N = 100
seed(1)
for i in range(N):
a = choice([1, -1]) * randint(1, 1<<randint(10, 100))
b = choice([1, -1]) * randint(1, 1<<randint(10, 100))
p = a * b
width = bitcount(abs(b)) - trailing(b)
a = fi(a); b = fi(b); p = fi(p)
for mode in all_modes:
assert mpf_div(p, a, width, mode) == b
def test_epsilon_rounding():
# Verify that mpf_div uses infinite precision; this result will
# appear to be exactly 0.101 to a near-sighted algorithm
a = fb('0.101' + ('0'*200) + '1')
b = fb('1.10101')
c = mpf_mul(a, b, 250, round_floor) # exact
assert mpf_div(c, b, bitcount(a[1]), round_floor) == a # exact
assert mpf_div(c, b, 2, round_down) == fb('0.10')
assert mpf_div(c, b, 3, round_down) == fb('0.101')
assert mpf_div(c, b, 2, round_up) == fb('0.11')
assert mpf_div(c, b, 3, round_up) == fb('0.110')
assert mpf_div(c, b, 2, round_floor) == fb('0.10')
assert mpf_div(c, b, 3, round_floor) == fb('0.101')
assert mpf_div(c, b, 2, round_ceiling) == fb('0.11')
assert mpf_div(c, b, 3, round_ceiling) == fb('0.110')
# The same for negative numbers
a = fb('-0.101' + ('0'*200) + '1')
b = fb('1.10101')
c = mpf_mul(a, b, 250, round_floor)
assert mpf_div(c, b, bitcount(a[1]), round_floor) == a
assert mpf_div(c, b, 2, round_down) == fb('-0.10')
assert mpf_div(c, b, 3, round_up) == fb('-0.110')
# Floor goes up, ceiling goes down
assert mpf_div(c, b, 2, round_floor) == fb('-0.11')
assert mpf_div(c, b, 3, round_floor) == fb('-0.110')
assert mpf_div(c, b, 2, round_ceiling) == fb('-0.10')
assert mpf_div(c, b, 3, round_ceiling) == fb('-0.101')
def test_mod():
mp.dps = 15
assert mpf(234) % 1 == 0
assert mpf(-3) % 256 == 253
assert mpf(0.25) % 23490.5 == 0.25
assert mpf(0.25) % -23490.5 == -23490.25
assert mpf(-0.25) % 23490.5 == 23490.25
assert mpf(-0.25) % -23490.5 == -0.25
# Check that these cases are handled efficiently
assert mpf('1e10000000000') % 1 == 0
assert mpf('1.23e-1000000000') % 1 == mpf('1.23e-1000000000')
# test __rmod__
assert 3 % mpf('1.75') == 1.25
def test_div_negative_rnd_bug():
mp.dps = 15
assert (-3) / mpf('0.1531879017645047') == mpf('-19.583791966887116')
assert mpf('-2.6342475750861301') / mpf('0.35126216427941814') == mpf('-7.4993775104985909')

View File

@ -0,0 +1,179 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
from mpmath import mp
from mpmath import libmp
xrange = libmp.backend.xrange
def run_hessenberg(A, verbose = 0):
if verbose > 1:
print("original matrix (hessenberg):\n", A)
n = A.rows
Q, H = mp.hessenberg(A)
if verbose > 1:
print("Q:\n",Q)
print("H:\n",H)
B = Q * H * Q.transpose_conj()
eps = mp.exp(0.8 * mp.log(mp.eps))
err0 = 0
for x in xrange(n):
for y in xrange(n):
err0 += abs(A[y,x] - B[y,x])
err0 /= n * n
err1 = 0
for x in xrange(n):
for y in xrange(x + 2, n):
err1 += abs(H[y,x])
if verbose > 0:
print("difference (H):", err0, err1)
if verbose > 1:
print("B:\n", B)
assert err0 < eps
assert err1 == 0
def run_schur(A, verbose = 0):
if verbose > 1:
print("original matrix (schur):\n", A)
n = A.rows
Q, R = mp.schur(A)
if verbose > 1:
print("Q:\n", Q)
print("R:\n", R)
B = Q * R * Q.transpose_conj()
C = Q * Q.transpose_conj()
eps = mp.exp(0.8 * mp.log(mp.eps))
err0 = 0
for x in xrange(n):
for y in xrange(n):
err0 += abs(A[y,x] - B[y,x])
err0 /= n * n
err1 = 0
for x in xrange(n):
for y in xrange(n):
if x == y:
C[y,x] -= 1
err1 += abs(C[y,x])
err1 /= n * n
err2 = 0
for x in xrange(n):
for y in xrange(x + 1, n):
err2 += abs(R[y,x])
if verbose > 0:
print("difference (S):", err0, err1, err2)
if verbose > 1:
print("B:\n", B)
assert err0 < eps
assert err1 < eps
assert err2 == 0
def run_eig(A, verbose = 0):
if verbose > 1:
print("original matrix (eig):\n", A)
n = A.rows
E, EL, ER = mp.eig(A, left = True, right = True)
if verbose > 1:
print("E:\n", E)
print("EL:\n", EL)
print("ER:\n", ER)
eps = mp.exp(0.8 * mp.log(mp.eps))
err0 = 0
for i in xrange(n):
B = A * ER[:,i] - E[i] * ER[:,i]
err0 = max(err0, mp.mnorm(B))
B = EL[i,:] * A - EL[i,:] * E[i]
err0 = max(err0, mp.mnorm(B))
err0 /= n * n
if verbose > 0:
print("difference (E):", err0)
assert err0 < eps
#####################
def test_eig_dyn():
v = 0
for i in xrange(5):
n = 1 + int(mp.rand() * 5)
if mp.rand() > 0.5:
# real
A = 2 * mp.randmatrix(n, n) - 1
if mp.rand() > 0.5:
A *= 10
for x in xrange(n):
for y in xrange(n):
A[x,y] = int(A[x,y])
else:
A = (2 * mp.randmatrix(n, n) - 1) + 1j * (2 * mp.randmatrix(n, n) - 1)
if mp.rand() > 0.5:
A *= 10
for x in xrange(n):
for y in xrange(n):
A[x,y] = int(mp.re(A[x,y])) + 1j * int(mp.im(A[x,y]))
run_hessenberg(A, verbose = v)
run_schur(A, verbose = v)
run_eig(A, verbose = v)
def test_eig():
v = 0
AS = []
A = mp.matrix([[2, 1, 0], # jordan block of size 3
[0, 2, 1],
[0, 0, 2]])
AS.append(A)
AS.append(A.transpose())
A = mp.matrix([[2, 0, 0], # jordan block of size 2
[0, 2, 1],
[0, 0, 2]])
AS.append(A)
AS.append(A.transpose())
A = mp.matrix([[2, 0, 1], # jordan block of size 2
[0, 2, 0],
[0, 0, 2]])
AS.append(A)
AS.append(A.transpose())
A= mp.matrix([[0, 0, 1], # cyclic
[1, 0, 0],
[0, 1, 0]])
AS.append(A)
AS.append(A.transpose())
for A in AS:
run_hessenberg(A, verbose = v)
run_schur(A, verbose = v)
run_eig(A, verbose = v)

View File

@ -0,0 +1,357 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
from mpmath import mp
from mpmath import libmp
xrange = libmp.backend.xrange
def run_eigsy(A, verbose = False):
if verbose:
print("original matrix:\n", str(A))
D, Q = mp.eigsy(A)
B = Q * mp.diag(D) * Q.transpose()
C = A - B
E = Q * Q.transpose() - mp.eye(A.rows)
if verbose:
print("eigenvalues:\n", D)
print("eigenvectors:\n", Q)
NC = mp.mnorm(C)
NE = mp.mnorm(E)
if verbose:
print("difference:", NC, "\n", C, "\n")
print("difference:", NE, "\n", E, "\n")
eps = mp.exp( 0.8 * mp.log(mp.eps))
assert NC < eps
assert NE < eps
return NC
def run_eighe(A, verbose = False):
if verbose:
print("original matrix:\n", str(A))
D, Q = mp.eighe(A)
B = Q * mp.diag(D) * Q.transpose_conj()
C = A - B
E = Q * Q.transpose_conj() - mp.eye(A.rows)
if verbose:
print("eigenvalues:\n", D)
print("eigenvectors:\n", Q)
NC = mp.mnorm(C)
NE = mp.mnorm(E)
if verbose:
print("difference:", NC, "\n", C, "\n")
print("difference:", NE, "\n", E, "\n")
eps = mp.exp( 0.8 * mp.log(mp.eps))
assert NC < eps
assert NE < eps
return NC
def run_svd_r(A, full_matrices = False, verbose = True):
m, n = A.rows, A.cols
eps = mp.exp(0.8 * mp.log(mp.eps))
if verbose:
print("original matrix:\n", str(A))
print("full", full_matrices)
U, S0, V = mp.svd_r(A, full_matrices = full_matrices)
S = mp.zeros(U.cols, V.rows)
for j in xrange(min(m, n)):
S[j,j] = S0[j]
if verbose:
print("U:\n", str(U))
print("S:\n", str(S0))
print("V:\n", str(V))
C = U * S * V - A
err = mp.mnorm(C)
if verbose:
print("C\n", str(C), "\n", err)
assert err < eps
D = V * V.transpose() - mp.eye(V.rows)
err = mp.mnorm(D)
if verbose:
print("D:\n", str(D), "\n", err)
assert err < eps
E = U.transpose() * U - mp.eye(U.cols)
err = mp.mnorm(E)
if verbose:
print("E:\n", str(E), "\n", err)
assert err < eps
def run_svd_c(A, full_matrices = False, verbose = True):
m, n = A.rows, A.cols
eps = mp.exp(0.8 * mp.log(mp.eps))
if verbose:
print("original matrix:\n", str(A))
print("full", full_matrices)
U, S0, V = mp.svd_c(A, full_matrices = full_matrices)
S = mp.zeros(U.cols, V.rows)
for j in xrange(min(m, n)):
S[j,j] = S0[j]
if verbose:
print("U:\n", str(U))
print("S:\n", str(S0))
print("V:\n", str(V))
C = U * S * V - A
err = mp.mnorm(C)
if verbose:
print("C\n", str(C), "\n", err)
assert err < eps
D = V * V.transpose_conj() - mp.eye(V.rows)
err = mp.mnorm(D)
if verbose:
print("D:\n", str(D), "\n", err)
assert err < eps
E = U.transpose_conj() * U - mp.eye(U.cols)
err = mp.mnorm(E)
if verbose:
print("E:\n", str(E), "\n", err)
assert err < eps
def run_gauss(qtype, a, b):
eps = 1e-5
d, e = mp.gauss_quadrature(len(a), qtype)
d -= mp.matrix(a)
e -= mp.matrix(b)
assert mp.mnorm(d) < eps
assert mp.mnorm(e) < eps
def irandmatrix(n, range = 10):
"""
random matrix with integer entries
"""
A = mp.matrix(n, n)
for i in xrange(n):
for j in xrange(n):
A[i,j]=int( (2 * mp.rand() - 1) * range)
return A
#######################
def test_eighe_fixed_matrix():
A = mp.matrix([[2, 3], [3, 5]])
run_eigsy(A)
run_eighe(A)
A = mp.matrix([[7, -11], [-11, 13]])
run_eigsy(A)
run_eighe(A)
A = mp.matrix([[2, 11, 7], [11, 3, 13], [7, 13, 5]])
run_eigsy(A)
run_eighe(A)
A = mp.matrix([[2, 0, 7], [0, 3, 1], [7, 1, 5]])
run_eigsy(A)
run_eighe(A)
#
A = mp.matrix([[2, 3+7j], [3-7j, 5]])
run_eighe(A)
A = mp.matrix([[2, -11j, 0], [+11j, 3, 29j], [0, -29j, 5]])
run_eighe(A)
A = mp.matrix([[2, 11 + 17j, 7 + 19j], [11 - 17j, 3, -13 + 23j], [7 - 19j, -13 - 23j, 5]])
run_eighe(A)
def test_eigsy_randmatrix():
N = 5
for a in xrange(10):
A = 2 * mp.randmatrix(N, N) - 1
for i in xrange(0, N):
for j in xrange(i + 1, N):
A[j,i] = A[i,j]
run_eigsy(A)
def test_eighe_randmatrix():
N = 5
for a in xrange(10):
A = (2 * mp.randmatrix(N, N) - 1) + 1j * (2 * mp.randmatrix(N, N) - 1)
for i in xrange(0, N):
A[i,i] = mp.re(A[i,i])
for j in xrange(i + 1, N):
A[j,i] = mp.conj(A[i,j])
run_eighe(A)
def test_eigsy_irandmatrix():
N = 4
R = 4
for a in xrange(10):
A=irandmatrix(N, R)
for i in xrange(0, N):
for j in xrange(i + 1, N):
A[j,i] = A[i,j]
run_eigsy(A)
def test_eighe_irandmatrix():
N = 4
R = 4
for a in xrange(10):
A=irandmatrix(N, R) + 1j * irandmatrix(N, R)
for i in xrange(0, N):
A[i,i] = mp.re(A[i,i])
for j in xrange(i + 1, N):
A[j,i] = mp.conj(A[i,j])
run_eighe(A)
def test_svd_r_rand():
for i in xrange(5):
full = mp.rand() > 0.5
m = 1 + int(mp.rand() * 10)
n = 1 + int(mp.rand() * 10)
A = 2 * mp.randmatrix(m, n) - 1
if mp.rand() > 0.5:
A *= 10
for x in xrange(m):
for y in xrange(n):
A[x,y]=int(A[x,y])
run_svd_r(A, full_matrices = full, verbose = False)
def test_svd_c_rand():
for i in xrange(5):
full = mp.rand() > 0.5
m = 1 + int(mp.rand() * 10)
n = 1 + int(mp.rand() * 10)
A = (2 * mp.randmatrix(m, n) - 1) + 1j * (2 * mp.randmatrix(m, n) - 1)
if mp.rand() > 0.5:
A *= 10
for x in xrange(m):
for y in xrange(n):
A[x,y]=int(mp.re(A[x,y])) + 1j * int(mp.im(A[x,y]))
run_svd_c(A, full_matrices=full, verbose=False)
def test_svd_test_case():
# a test case from Golub and Reinsch
# (see wilkinson/reinsch: handbook for auto. comp., vol ii-linear algebra, 134-151(1971).)
eps = mp.exp(0.8 * mp.log(mp.eps))
a = [[22, 10, 2, 3, 7],
[14, 7, 10, 0, 8],
[-1, 13, -1, -11, 3],
[-3, -2, 13, -2, 4],
[ 9, 8, 1, -2, 4],
[ 9, 1, -7, 5, -1],
[ 2, -6, 6, 5, 1],
[ 4, 5, 0, -2, 2]]
a = mp.matrix(a)
b = mp.matrix([mp.sqrt(1248), 20, mp.sqrt(384), 0, 0])
S = mp.svd_r(a, compute_uv = False)
S -= b
assert mp.mnorm(S) < eps
S = mp.svd_c(a, compute_uv = False)
S -= b
assert mp.mnorm(S) < eps
def test_gauss_quadrature_static():
a = [-0.57735027, 0.57735027]
b = [ 1, 1]
run_gauss("legendre", a , b)
a = [ -0.906179846, -0.538469310, 0, 0.538469310, 0.906179846]
b = [ 0.23692689, 0.47862867, 0.56888889, 0.47862867, 0.23692689]
run_gauss("legendre", a , b)
a = [ 0.06943184, 0.33000948, 0.66999052, 0.93056816]
b = [ 0.17392742, 0.32607258, 0.32607258, 0.17392742]
run_gauss("legendre01", a , b)
a = [-0.70710678, 0.70710678]
b = [ 0.88622693, 0.88622693]
run_gauss("hermite", a , b)
a = [ -2.02018287, -0.958572465, 0, 0.958572465, 2.02018287]
b = [ 0.01995324, 0.39361932, 0.94530872, 0.39361932, 0.01995324]
run_gauss("hermite", a , b)
a = [ 0.41577456, 2.29428036, 6.28994508]
b = [ 0.71109301, 0.27851773, 0.01038926]
run_gauss("laguerre", a , b)
def test_gauss_quadrature_dynamic(verbose = False):
n = 5
A = mp.randmatrix(2 * n, 1)
def F(x):
r = 0
for i in xrange(len(A) - 1, -1, -1):
r = r * x + A[i]
return r
def run(qtype, FW, R, alpha = 0, beta = 0):
X, W = mp.gauss_quadrature(n, qtype, alpha = alpha, beta = beta)
a = 0
for i in xrange(len(X)):
a += W[i] * F(X[i])
b = mp.quad(lambda x: FW(x) * F(x), R)
c = mp.fabs(a - b)
if verbose:
print(qtype, c, a, b)
assert c < 1e-5
run("legendre", lambda x: 1, [-1, 1])
run("legendre01", lambda x: 1, [0, 1])
run("hermite", lambda x: mp.exp(-x*x), [-mp.inf, mp.inf])
run("laguerre", lambda x: mp.exp(-x), [0, mp.inf])
run("glaguerre", lambda x: mp.sqrt(x)*mp.exp(-x), [0, mp.inf], alpha = 1 / mp.mpf(2))
run("chebyshev1", lambda x: 1/mp.sqrt(1-x*x), [-1, 1])
run("chebyshev2", lambda x: mp.sqrt(1-x*x), [-1, 1])
run("jacobi", lambda x: (1-x)**(1/mp.mpf(3)) * (1+x)**(1/mp.mpf(5)), [-1, 1], alpha = 1 / mp.mpf(3), beta = 1 / mp.mpf(5) )

View File

@ -0,0 +1,670 @@
"""
Limited tests of the elliptic functions module. A full suite of
extensive testing can be found in elliptic_torture_tests.py
Author of the first version: M.T. Taschuk
References:
[1] Abramowitz & Stegun. 'Handbook of Mathematical Functions, 9th Ed.',
(Dover duplicate of 1972 edition)
[2] Whittaker 'A Course of Modern Analysis, 4th Ed.', 1946,
Cambridge University Press
"""
import mpmath
import random
import pytest
from mpmath import *
def mpc_ae(a, b, eps=eps):
res = True
res = res and a.real.ae(b.real, eps)
res = res and a.imag.ae(b.imag, eps)
return res
zero = mpf(0)
one = mpf(1)
jsn = ellipfun('sn')
jcn = ellipfun('cn')
jdn = ellipfun('dn')
calculate_nome = lambda k: qfrom(k=k)
def test_ellipfun():
mp.dps = 15
assert ellipfun('ss', 0, 0) == 1
assert ellipfun('cc', 0, 0) == 1
assert ellipfun('dd', 0, 0) == 1
assert ellipfun('nn', 0, 0) == 1
assert ellipfun('sn', 0.25, 0).ae(sin(0.25))
assert ellipfun('cn', 0.25, 0).ae(cos(0.25))
assert ellipfun('dn', 0.25, 0).ae(1)
assert ellipfun('ns', 0.25, 0).ae(csc(0.25))
assert ellipfun('nc', 0.25, 0).ae(sec(0.25))
assert ellipfun('nd', 0.25, 0).ae(1)
assert ellipfun('sc', 0.25, 0).ae(tan(0.25))
assert ellipfun('sd', 0.25, 0).ae(sin(0.25))
assert ellipfun('cd', 0.25, 0).ae(cos(0.25))
assert ellipfun('cs', 0.25, 0).ae(cot(0.25))
assert ellipfun('dc', 0.25, 0).ae(sec(0.25))
assert ellipfun('ds', 0.25, 0).ae(csc(0.25))
assert ellipfun('sn', 0.25, 1).ae(tanh(0.25))
assert ellipfun('cn', 0.25, 1).ae(sech(0.25))
assert ellipfun('dn', 0.25, 1).ae(sech(0.25))
assert ellipfun('ns', 0.25, 1).ae(coth(0.25))
assert ellipfun('nc', 0.25, 1).ae(cosh(0.25))
assert ellipfun('nd', 0.25, 1).ae(cosh(0.25))
assert ellipfun('sc', 0.25, 1).ae(sinh(0.25))
assert ellipfun('sd', 0.25, 1).ae(sinh(0.25))
assert ellipfun('cd', 0.25, 1).ae(1)
assert ellipfun('cs', 0.25, 1).ae(csch(0.25))
assert ellipfun('dc', 0.25, 1).ae(1)
assert ellipfun('ds', 0.25, 1).ae(csch(0.25))
assert ellipfun('sn', 0.25, 0.5).ae(0.24615967096986145833)
assert ellipfun('cn', 0.25, 0.5).ae(0.96922928989378439337)
assert ellipfun('dn', 0.25, 0.5).ae(0.98473484156599474563)
assert ellipfun('ns', 0.25, 0.5).ae(4.0624038700573130369)
assert ellipfun('nc', 0.25, 0.5).ae(1.0317476065024692949)
assert ellipfun('nd', 0.25, 0.5).ae(1.0155017958029488665)
assert ellipfun('sc', 0.25, 0.5).ae(0.25397465134058993408)
assert ellipfun('sd', 0.25, 0.5).ae(0.24997558792415733063)
assert ellipfun('cd', 0.25, 0.5).ae(0.98425408443195497052)
assert ellipfun('cs', 0.25, 0.5).ae(3.9374008182374110826)
assert ellipfun('dc', 0.25, 0.5).ae(1.0159978158253033913)
assert ellipfun('ds', 0.25, 0.5).ae(4.0003906313579720593)
def test_calculate_nome():
mp.dps = 100
q = calculate_nome(zero)
assert(q == zero)
mp.dps = 25
# used Mathematica's EllipticNomeQ[m]
math1 = [(mpf(1)/10, mpf('0.006584651553858370274473060')),
(mpf(2)/10, mpf('0.01394285727531826872146409')),
(mpf(3)/10, mpf('0.02227743615715350822901627')),
(mpf(4)/10, mpf('0.03188334731336317755064299')),
(mpf(5)/10, mpf('0.04321391826377224977441774')),
(mpf(6)/10, mpf('0.05702025781460967637754953')),
(mpf(7)/10, mpf('0.07468994353717944761143751')),
(mpf(8)/10, mpf('0.09927369733882489703607378')),
(mpf(9)/10, mpf('0.1401731269542615524091055')),
(mpf(9)/10, mpf('0.1401731269542615524091055'))]
for i in math1:
m = i[0]
q = calculate_nome(sqrt(m))
assert q.ae(i[1])
mp.dps = 15
def test_jtheta():
mp.dps = 25
z = q = zero
for n in range(1,5):
value = jtheta(n, z, q)
assert(value == (n-1)//2)
for q in [one, mpf(2)]:
for n in range(1,5):
pytest.raises(ValueError, lambda: jtheta(n, z, q))
z = one/10
q = one/11
# Mathematical N[EllipticTheta[1, 1/10, 1/11], 25]
res = mpf('0.1069552990104042681962096')
result = jtheta(1, z, q)
assert(result.ae(res))
# Mathematica N[EllipticTheta[2, 1/10, 1/11], 25]
res = mpf('1.101385760258855791140606')
result = jtheta(2, z, q)
assert(result.ae(res))
# Mathematica N[EllipticTheta[3, 1/10, 1/11], 25]
res = mpf('1.178319743354331061795905')
result = jtheta(3, z, q)
assert(result.ae(res))
# Mathematica N[EllipticTheta[4, 1/10, 1/11], 25]
res = mpf('0.8219318954665153577314573')
result = jtheta(4, z, q)
assert(result.ae(res))
# test for sin zeros for jtheta(1, z, q)
# test for cos zeros for jtheta(2, z, q)
z1 = pi
z2 = pi/2
for i in range(10):
qstring = str(random.random())
q = mpf(qstring)
result = jtheta(1, z1, q)
assert(result.ae(0))
result = jtheta(2, z2, q)
assert(result.ae(0))
mp.dps = 15
def test_jtheta_issue_79():
# near the circle of covergence |q| = 1 the convergence slows
# down; for |q| > Q_LIM the theta functions raise ValueError
mp.dps = 30
mp.dps += 30
q = mpf(6)/10 - one/10**6 - mpf(8)/10 * j
mp.dps -= 30
# Mathematica run first
# N[EllipticTheta[3, 1, 6/10 - 10^-6 - 8/10*I], 2000]
# then it works:
# N[EllipticTheta[3, 1, 6/10 - 10^-6 - 8/10*I], 30]
res = mpf('32.0031009628901652627099524264') + \
mpf('16.6153027998236087899308935624') * j
result = jtheta(3, 1, q)
# check that for abs(q) > Q_LIM a ValueError exception is raised
mp.dps += 30
q = mpf(6)/10 - one/10**7 - mpf(8)/10 * j
mp.dps -= 30
pytest.raises(ValueError, lambda: jtheta(3, 1, q))
# bug reported in issue 79
mp.dps = 100
z = (1+j)/3
q = mpf(368983957219251)/10**15 + mpf(636363636363636)/10**15 * j
# Mathematica N[EllipticTheta[1, z, q], 35]
res = mpf('2.4439389177990737589761828991467471') + \
mpf('0.5446453005688226915290954851851490') *j
mp.dps = 30
result = jtheta(1, z, q)
assert(result.ae(res))
mp.dps = 80
z = 3 + 4*j
q = 0.5 + 0.5*j
r1 = jtheta(1, z, q)
mp.dps = 15
r2 = jtheta(1, z, q)
assert r1.ae(r2)
mp.dps = 80
z = 3 + j
q1 = exp(j*3)
# longer test
# for n in range(1, 6)
for n in range(1, 2):
mp.dps = 80
q = q1*(1 - mpf(1)/10**n)
r1 = jtheta(1, z, q)
mp.dps = 15
r2 = jtheta(1, z, q)
assert r1.ae(r2)
mp.dps = 15
# issue 79 about high derivatives
assert jtheta(3, 4.5, 0.25, 9).ae(1359.04892680683)
assert jtheta(3, 4.5, 0.25, 50).ae(-6.14832772630905e+33)
mp.dps = 50
r = jtheta(3, 4.5, 0.25, 9)
assert r.ae('1359.048926806828939547859396600218966947753213803')
r = jtheta(3, 4.5, 0.25, 50)
assert r.ae('-6148327726309051673317975084654262.4119215720343656')
def test_jtheta_identities():
"""
Tests the some of the jacobi identidies found in Abramowitz,
Sec. 16.28, Pg. 576. The identities are tested to 1 part in 10^98.
"""
mp.dps = 110
eps1 = ldexp(eps, 30)
for i in range(10):
qstring = str(random.random())
q = mpf(qstring)
zstring = str(10*random.random())
z = mpf(zstring)
# Abramowitz 16.28.1
# v_1(z, q)**2 * v_4(0, q)**2 = v_3(z, q)**2 * v_2(0, q)**2
# - v_2(z, q)**2 * v_3(0, q)**2
term1 = (jtheta(1, z, q)**2) * (jtheta(4, zero, q)**2)
term2 = (jtheta(3, z, q)**2) * (jtheta(2, zero, q)**2)
term3 = (jtheta(2, z, q)**2) * (jtheta(3, zero, q)**2)
equality = term1 - term2 + term3
assert(equality.ae(0, eps1))
zstring = str(100*random.random())
z = mpf(zstring)
# Abramowitz 16.28.2
# v_2(z, q)**2 * v_4(0, q)**2 = v_4(z, q)**2 * v_2(0, q)**2
# - v_1(z, q)**2 * v_3(0, q)**2
term1 = (jtheta(2, z, q)**2) * (jtheta(4, zero, q)**2)
term2 = (jtheta(4, z, q)**2) * (jtheta(2, zero, q)**2)
term3 = (jtheta(1, z, q)**2) * (jtheta(3, zero, q)**2)
equality = term1 - term2 + term3
assert(equality.ae(0, eps1))
# Abramowitz 16.28.3
# v_3(z, q)**2 * v_4(0, q)**2 = v_4(z, q)**2 * v_3(0, q)**2
# - v_1(z, q)**2 * v_2(0, q)**2
term1 = (jtheta(3, z, q)**2) * (jtheta(4, zero, q)**2)
term2 = (jtheta(4, z, q)**2) * (jtheta(3, zero, q)**2)
term3 = (jtheta(1, z, q)**2) * (jtheta(2, zero, q)**2)
equality = term1 - term2 + term3
assert(equality.ae(0, eps1))
# Abramowitz 16.28.4
# v_4(z, q)**2 * v_4(0, q)**2 = v_3(z, q)**2 * v_3(0, q)**2
# - v_2(z, q)**2 * v_2(0, q)**2
term1 = (jtheta(4, z, q)**2) * (jtheta(4, zero, q)**2)
term2 = (jtheta(3, z, q)**2) * (jtheta(3, zero, q)**2)
term3 = (jtheta(2, z, q)**2) * (jtheta(2, zero, q)**2)
equality = term1 - term2 + term3
assert(equality.ae(0, eps1))
# Abramowitz 16.28.5
# v_2(0, q)**4 + v_4(0, q)**4 == v_3(0, q)**4
term1 = (jtheta(2, zero, q))**4
term2 = (jtheta(4, zero, q))**4
term3 = (jtheta(3, zero, q))**4
equality = term1 + term2 - term3
assert(equality.ae(0, eps1))
mp.dps = 15
def test_jtheta_complex():
mp.dps = 30
z = mpf(1)/4 + j/8
q = mpf(1)/3 + j/7
# Mathematica N[EllipticTheta[1, 1/4 + I/8, 1/3 + I/7], 35]
res = mpf('0.31618034835986160705729105731678285') + \
mpf('0.07542013825835103435142515194358975') * j
r = jtheta(1, z, q)
assert(mpc_ae(r, res))
# Mathematica N[EllipticTheta[2, 1/4 + I/8, 1/3 + I/7], 35]
res = mpf('1.6530986428239765928634711417951828') + \
mpf('0.2015344864707197230526742145361455') * j
r = jtheta(2, z, q)
assert(mpc_ae(r, res))
# Mathematica N[EllipticTheta[3, 1/4 + I/8, 1/3 + I/7], 35]
res = mpf('1.6520564411784228184326012700348340') + \
mpf('0.1998129119671271328684690067401823') * j
r = jtheta(3, z, q)
assert(mpc_ae(r, res))
# Mathematica N[EllipticTheta[4, 1/4 + I/8, 1/3 + I/7], 35]
res = mpf('0.37619082382228348252047624089973824') - \
mpf('0.15623022130983652972686227200681074') * j
r = jtheta(4, z, q)
assert(mpc_ae(r, res))
# check some theta function identities
mp.dos = 100
z = mpf(1)/4 + j/8
q = mpf(1)/3 + j/7
mp.dps += 10
a = [0,0, jtheta(2, 0, q), jtheta(3, 0, q), jtheta(4, 0, q)]
t = [0, jtheta(1, z, q), jtheta(2, z, q), jtheta(3, z, q), jtheta(4, z, q)]
r = [(t[2]*a[4])**2 - (t[4]*a[2])**2 + (t[1] *a[3])**2,
(t[3]*a[4])**2 - (t[4]*a[3])**2 + (t[1] *a[2])**2,
(t[1]*a[4])**2 - (t[3]*a[2])**2 + (t[2] *a[3])**2,
(t[4]*a[4])**2 - (t[3]*a[3])**2 + (t[2] *a[2])**2,
a[2]**4 + a[4]**4 - a[3]**4]
mp.dps -= 10
for x in r:
assert(mpc_ae(x, mpc(0)))
mp.dps = 15
def test_djtheta():
mp.dps = 30
z = one/7 + j/3
q = one/8 + j/5
# Mathematica N[EllipticThetaPrime[1, 1/7 + I/3, 1/8 + I/5], 35]
res = mpf('1.5555195883277196036090928995803201') - \
mpf('0.02439761276895463494054149673076275') * j
result = jtheta(1, z, q, 1)
assert(mpc_ae(result, res))
# Mathematica N[EllipticThetaPrime[2, 1/7 + I/3, 1/8 + I/5], 35]
res = mpf('0.19825296689470982332701283509685662') - \
mpf('0.46038135182282106983251742935250009') * j
result = jtheta(2, z, q, 1)
assert(mpc_ae(result, res))
# Mathematica N[EllipticThetaPrime[3, 1/7 + I/3, 1/8 + I/5], 35]
res = mpf('0.36492498415476212680896699407390026') - \
mpf('0.57743812698666990209897034525640369') * j
result = jtheta(3, z, q, 1)
assert(mpc_ae(result, res))
# Mathematica N[EllipticThetaPrime[4, 1/7 + I/3, 1/8 + I/5], 35]
res = mpf('-0.38936892528126996010818803742007352') + \
mpf('0.66549886179739128256269617407313625') * j
result = jtheta(4, z, q, 1)
assert(mpc_ae(result, res))
for i in range(10):
q = (one*random.random() + j*random.random())/2
# identity in Wittaker, Watson &21.41
a = jtheta(1, 0, q, 1)
b = jtheta(2, 0, q)*jtheta(3, 0, q)*jtheta(4, 0, q)
assert(a.ae(b))
# test higher derivatives
mp.dps = 20
for q,z in [(one/3, one/5), (one/3 + j/8, one/5),
(one/3, one/5 + j/8), (one/3 + j/7, one/5 + j/8)]:
for n in [1, 2, 3, 4]:
r = jtheta(n, z, q, 2)
r1 = diff(lambda zz: jtheta(n, zz, q), z, n=2)
assert r.ae(r1)
r = jtheta(n, z, q, 3)
r1 = diff(lambda zz: jtheta(n, zz, q), z, n=3)
assert r.ae(r1)
# identity in Wittaker, Watson &21.41
q = one/3
z = zero
a = [0]*5
a[1] = jtheta(1, z, q, 3)/jtheta(1, z, q, 1)
for n in [2,3,4]:
a[n] = jtheta(n, z, q, 2)/jtheta(n, z, q)
equality = a[2] + a[3] + a[4] - a[1]
assert(equality.ae(0))
mp.dps = 15
def test_jsn():
"""
Test some special cases of the sn(z, q) function.
"""
mp.dps = 100
# trival case
result = jsn(zero, zero)
assert(result == zero)
# Abramowitz Table 16.5
#
# sn(0, m) = 0
for i in range(10):
qstring = str(random.random())
q = mpf(qstring)
equality = jsn(zero, q)
assert(equality.ae(0))
# Abramowitz Table 16.6.1
#
# sn(z, 0) = sin(z), m == 0
#
# sn(z, 1) = tanh(z), m == 1
#
# It would be nice to test these, but I find that they run
# in to numerical trouble. I'm currently treating as a boundary
# case for sn function.
mp.dps = 25
arg = one/10
#N[JacobiSN[1/10, 2^-100], 25]
res = mpf('0.09983341664682815230681420')
m = ldexp(one, -100)
result = jsn(arg, m)
assert(result.ae(res))
# N[JacobiSN[1/10, 1/10], 25]
res = mpf('0.09981686718599080096451168')
result = jsn(arg, arg)
assert(result.ae(res))
mp.dps = 15
def test_jcn():
"""
Test some special cases of the cn(z, q) function.
"""
mp.dps = 100
# Abramowitz Table 16.5
# cn(0, q) = 1
qstring = str(random.random())
q = mpf(qstring)
cn = jcn(zero, q)
assert(cn.ae(one))
# Abramowitz Table 16.6.2
#
# cn(u, 0) = cos(u), m == 0
#
# cn(u, 1) = sech(z), m == 1
#
# It would be nice to test these, but I find that they run
# in to numerical trouble. I'm currently treating as a boundary
# case for cn function.
mp.dps = 25
arg = one/10
m = ldexp(one, -100)
#N[JacobiCN[1/10, 2^-100], 25]
res = mpf('0.9950041652780257660955620')
result = jcn(arg, m)
assert(result.ae(res))
# N[JacobiCN[1/10, 1/10], 25]
res = mpf('0.9950058256237368748520459')
result = jcn(arg, arg)
assert(result.ae(res))
mp.dps = 15
def test_jdn():
"""
Test some special cases of the dn(z, q) function.
"""
mp.dps = 100
# Abramowitz Table 16.5
# dn(0, q) = 1
mstring = str(random.random())
m = mpf(mstring)
dn = jdn(zero, m)
assert(dn.ae(one))
mp.dps = 25
# N[JacobiDN[1/10, 1/10], 25]
res = mpf('0.9995017055025556219713297')
arg = one/10
result = jdn(arg, arg)
assert(result.ae(res))
mp.dps = 15
def test_sn_cn_dn_identities():
"""
Tests the some of the jacobi elliptic function identities found
on Mathworld. Haven't found in Abramowitz.
"""
mp.dps = 100
N = 5
for i in range(N):
qstring = str(random.random())
q = mpf(qstring)
zstring = str(100*random.random())
z = mpf(zstring)
# MathWorld
# sn(z, q)**2 + cn(z, q)**2 == 1
term1 = jsn(z, q)**2
term2 = jcn(z, q)**2
equality = one - term1 - term2
assert(equality.ae(0))
# MathWorld
# k**2 * sn(z, m)**2 + dn(z, m)**2 == 1
for i in range(N):
mstring = str(random.random())
m = mpf(qstring)
k = m.sqrt()
zstring = str(10*random.random())
z = mpf(zstring)
term1 = k**2 * jsn(z, m)**2
term2 = jdn(z, m)**2
equality = one - term1 - term2
assert(equality.ae(0))
for i in range(N):
mstring = str(random.random())
m = mpf(mstring)
k = m.sqrt()
zstring = str(random.random())
z = mpf(zstring)
# MathWorld
# k**2 * cn(z, m)**2 + (1 - k**2) = dn(z, m)**2
term1 = k**2 * jcn(z, m)**2
term2 = 1 - k**2
term3 = jdn(z, m)**2
equality = term3 - term1 - term2
assert(equality.ae(0))
K = ellipk(k**2)
# Abramowitz Table 16.5
# sn(K, m) = 1; K is K(k), first complete elliptic integral
r = jsn(K, m)
assert(r.ae(one))
# Abramowitz Table 16.5
# cn(K, q) = 0; K is K(k), first complete elliptic integral
equality = jcn(K, m)
assert(equality.ae(0))
# Abramowitz Table 16.6.3
# dn(z, 0) = 1, m == 0
z = m
value = jdn(z, zero)
assert(value.ae(one))
mp.dps = 15
def test_sn_cn_dn_complex():
mp.dps = 30
# N[JacobiSN[1/4 + I/8, 1/3 + I/7], 35] in Mathematica
res = mpf('0.2495674401066275492326652143537') + \
mpf('0.12017344422863833381301051702823') * j
u = mpf(1)/4 + j/8
m = mpf(1)/3 + j/7
r = jsn(u, m)
assert(mpc_ae(r, res))
#N[JacobiCN[1/4 + I/8, 1/3 + I/7], 35]
res = mpf('0.9762691700944007312693721148331') - \
mpf('0.0307203994181623243583169154824')*j
r = jcn(u, m)
#assert r.real.ae(res.real)
#assert r.imag.ae(res.imag)
assert(mpc_ae(r, res))
#N[JacobiDN[1/4 + I/8, 1/3 + I/7], 35]
res = mpf('0.99639490163039577560547478589753039') - \
mpf('0.01346296520008176393432491077244994')*j
r = jdn(u, m)
assert(mpc_ae(r, res))
mp.dps = 15
def test_elliptic_integrals():
# Test cases from Carlson's paper
mp.dps = 15
assert elliprd(0,2,1).ae(1.7972103521033883112)
assert elliprd(2,3,4).ae(0.16510527294261053349)
assert elliprd(j,-j,2).ae(0.65933854154219768919)
assert elliprd(0,j,-j).ae(1.2708196271909686299 + 2.7811120159520578777j)
assert elliprd(0,j-1,j).ae(-1.8577235439239060056 - 0.96193450888838559989j)
assert elliprd(-2-j,-j,-1+j).ae(1.8249027393703805305 - 1.2218475784827035855j)
# extra test cases
assert elliprg(0,0,0) == 0
assert elliprg(0,0,16).ae(2)
assert elliprg(0,16,0).ae(2)
assert elliprg(16,0,0).ae(2)
assert elliprg(1,4,0).ae(1.2110560275684595248036)
assert elliprg(1,0,4).ae(1.2110560275684595248036)
assert elliprg(0,4,1).ae(1.2110560275684595248036)
# should be symmetric -- fixes a bug present in the paper
x,y,z = 1,1j,-1+1j
assert elliprg(x,y,z).ae(0.64139146875812627545 + 0.58085463774808290907j)
assert elliprg(x,z,y).ae(0.64139146875812627545 + 0.58085463774808290907j)
assert elliprg(y,x,z).ae(0.64139146875812627545 + 0.58085463774808290907j)
assert elliprg(y,z,x).ae(0.64139146875812627545 + 0.58085463774808290907j)
assert elliprg(z,x,y).ae(0.64139146875812627545 + 0.58085463774808290907j)
assert elliprg(z,y,x).ae(0.64139146875812627545 + 0.58085463774808290907j)
for n in [5, 15, 30, 60, 100]:
mp.dps = n
assert elliprf(1,2,0).ae('1.3110287771460599052324197949455597068413774757158115814084108519003952935352071251151477664807145467230678763')
assert elliprf(0.5,1,0).ae('1.854074677301371918433850347195260046217598823521766905585928045056021776838119978357271861650371897277771871')
assert elliprf(j,-j,0).ae('1.854074677301371918433850347195260046217598823521766905585928045056021776838119978357271861650371897277771871')
assert elliprf(j-1,j,0).ae(mpc('0.79612586584233913293056938229563057846592264089185680214929401744498956943287031832657642790719940442165621412',
'-1.2138566698364959864300942567386038975419875860741507618279563735753073152507112254567291141460317931258599889'))
assert elliprf(2,3,4).ae('0.58408284167715170669284916892566789240351359699303216166309375305508295130412919665541330837704050454472379308')
assert elliprf(j,-j,2).ae('1.0441445654064360931078658361850779139591660747973017593275012615517220315993723776182276555339288363064476126')
assert elliprf(j-1,j,1-j).ae(mpc('0.93912050218619371196624617169781141161485651998254431830645241993282941057500174238125105410055253623847335313',
'-0.53296252018635269264859303449447908970360344322834582313172115220559316331271520508208025270300138589669326136'))
assert elliprc(0,0.25).ae(+pi)
assert elliprc(2.25,2).ae(+ln2)
assert elliprc(0,j).ae(mpc('1.1107207345395915617539702475151734246536554223439225557713489017391086982748684776438317336911913093408525532',
'-1.1107207345395915617539702475151734246536554223439225557713489017391086982748684776438317336911913093408525532'))
assert elliprc(-j,j).ae(mpc('1.2260849569072198222319655083097718755633725139745941606203839524036426936825652935738621522906572884239069297',
'-0.34471136988767679699935618332997956653521218571295874986708834375026550946053920574015526038040124556716711353'))
assert elliprc(0.25,-2).ae(ln2/3)
assert elliprc(j,-1).ae(mpc('0.77778596920447389875196055840799837589537035343923012237628610795937014001905822029050288316217145443865649819',
'0.1983248499342877364755170948292130095921681309577950696116251029742793455964385947473103628983664877025779304'))
assert elliprj(0,1,2,3).ae('0.77688623778582332014190282640545501102298064276022952731669118325952563819813258230708177398475643634103990878')
assert elliprj(2,3,4,5).ae('0.14297579667156753833233879421985774801466647854232626336218889885463800128817976132826443904216546421431528308')
assert elliprj(2,3,4,-1+j).ae(mpc('0.13613945827770535203521374457913768360237593025944342652613569368333226052158214183059386307242563164036672709',
'-0.38207561624427164249600936454845112611060375760094156571007648297226090050927156176977091273224510621553615189'))
assert elliprj(j,-j,0,2).ae('1.6490011662710884518243257224860232300246792717163891216346170272567376981346412066066050103935109581019055806')
assert elliprj(-1+j,-1-j,1,2).ae('0.94148358841220238083044612133767270187474673547917988681610772381758628963408843935027667916713866133196845063')
assert elliprj(j,-j,0,1-j).ae(mpc('1.8260115229009316249372594065790946657011067182850435297162034335356430755397401849070610280860044610878657501',
'1.2290661908643471500163617732957042849283739403009556715926326841959667290840290081010472716420690899886276961'))
assert elliprj(-1+j,-1-j,1,-3+j).ae(mpc('-0.61127970812028172123588152373622636829986597243716610650831553882054127570542477508023027578037045504958619422',
'-1.0684038390006807880182112972232562745485871763154040245065581157751693730095703406209466903752930797510491155'))
assert elliprj(-1+j,-2-j,-j,-1+j).ae(mpc('1.8249027393703805304622013339009022294368078659619988943515764258335975852685224202567854526307030593012768954',
'-1.2218475784827035854568450371590419833166777535029296025352291308244564398645467465067845461070602841312456831'))
assert elliprg(0,16,16).ae(+pi)
assert elliprg(2,3,4).ae('1.7255030280692277601061148835701141842692457170470456590515892070736643637303053506944907685301315299153040991')
assert elliprg(0,j,-j).ae('0.42360654239698954330324956174109581824072295516347109253028968632986700241706737986160014699730561497106114281')
assert elliprg(j-1,j,0).ae(mpc('0.44660591677018372656731970402124510811555212083508861036067729944477855594654762496407405328607219895053798354',
'0.70768352357515390073102719507612395221369717586839400605901402910893345301718731499237159587077682267374159282'))
assert elliprg(-j,j-1,j).ae(mpc('0.36023392184473309033675652092928695596803358846377334894215349632203382573844427952830064383286995172598964266',
'0.40348623401722113740956336997761033878615232917480045914551915169013722542827052849476969199578321834819903921'))
assert elliprg(0, mpf('0.0796'), 4).ae('1.0284758090288040009838871385180217366569777284430590125081211090574701293154645750017813190805144572673802094')
mp.dps = 15
# more test cases for the branch of ellippi / elliprj
assert elliprj(-1-0.5j, -10-6j, -10-3j, -5+10j).ae(0.128470516743927699 + 0.102175950778504625j, abs_eps=1e-8)
assert elliprj(1.987, 4.463 - 1.614j, 0, -3.965).ae(-0.341575118513811305 - 0.394703757004268486j, abs_eps=1e-8)
assert elliprj(0.3068, -4.037+0.632j, 1.654, -0.9609).ae(-1.14735199581485639 - 0.134450158867472264j, abs_eps=1e-8)
assert elliprj(0.3068, -4.037-0.632j, 1.654, -0.9609).ae(1.758765901861727 - 0.161002343366626892j, abs_eps=1e-5)
assert elliprj(0.3068, -4.037+0.0632j, 1.654, -0.9609).ae(-1.17157627949475577 - 0.069182614173988811j, abs_eps=1e-8)
assert elliprj(0.3068, -4.037+0.00632j, 1.654, -0.9609).ae(-1.17337595670549633 - 0.0623069224526925j, abs_eps=1e-8)
# these require accurate integration
assert elliprj(0.3068, -4.037-0.0632j, 1.654, -0.9609).ae(1.77940452391261626 + 0.0388711305592447234j)
assert elliprj(0.3068, -4.037-0.00632j, 1.654, -0.9609).ae(1.77806722756403055 + 0.0592749824572262329j)
# issue #571
assert ellippi(2.1 + 0.94j, 2.3 + 0.98j, 2.5 + 0.01j).ae(-0.40652414240811963438 + 2.1547659461404749309j)
assert ellippi(2.0-1.0j, 2.0+1.0j).ae(1.8578723151271115 - 1.18642180609983531j)
assert ellippi(2.0-0.5j, 0.5+1.0j).ae(0.936761970766645807 - 1.61876787838890786j)
assert ellippi(2.0, 1.0+1.0j).ae(0.999881420735506708 - 2.4139272867045391j)
assert ellippi(2.0+1.0j, 2.0-1.0j).ae(1.8578723151271115 + 1.18642180609983531j)
assert ellippi(2.0+1.0j, 2.0).ae(2.78474654927885845 + 2.02204728966993314j)
def test_issue_238():
assert isnan(qfrom(m=nan))

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,920 @@
from mpmath.libmp import *
from mpmath import *
import random
import time
import math
import cmath
def mpc_ae(a, b, eps=eps):
res = True
res = res and a.real.ae(b.real, eps)
res = res and a.imag.ae(b.imag, eps)
return res
#----------------------------------------------------------------------------
# Constants and functions
#
tpi = "3.1415926535897932384626433832795028841971693993751058209749445923078\
1640628620899862803482534211706798"
te = "2.71828182845904523536028747135266249775724709369995957496696762772407\
663035354759457138217852516642743"
tdegree = "0.017453292519943295769236907684886127134428718885417254560971914\
4017100911460344944368224156963450948221"
teuler = "0.5772156649015328606065120900824024310421593359399235988057672348\
84867726777664670936947063291746749516"
tln2 = "0.693147180559945309417232121458176568075500134360255254120680009493\
393621969694715605863326996418687542"
tln10 = "2.30258509299404568401799145468436420760110148862877297603332790096\
757260967735248023599720508959829834"
tcatalan = "0.91596559417721901505460351493238411077414937428167213426649811\
9621763019776254769479356512926115106249"
tkhinchin = "2.6854520010653064453097148354817956938203822939944629530511523\
4555721885953715200280114117493184769800"
tglaisher = "1.2824271291006226368753425688697917277676889273250011920637400\
2174040630885882646112973649195820237439420646"
tapery = "1.2020569031595942853997381615114499907649862923404988817922715553\
4183820578631309018645587360933525815"
tphi = "1.618033988749894848204586834365638117720309179805762862135448622705\
26046281890244970720720418939113748475"
tmertens = "0.26149721284764278375542683860869585905156664826119920619206421\
3924924510897368209714142631434246651052"
ttwinprime = "0.660161815846869573927812110014555778432623360284733413319448\
423335405642304495277143760031413839867912"
def test_constants():
for prec in [3, 7, 10, 15, 20, 37, 80, 100, 29]:
mp.dps = prec
assert pi == mpf(tpi)
assert e == mpf(te)
assert degree == mpf(tdegree)
assert euler == mpf(teuler)
assert ln2 == mpf(tln2)
assert ln10 == mpf(tln10)
assert catalan == mpf(tcatalan)
assert khinchin == mpf(tkhinchin)
assert glaisher == mpf(tglaisher)
assert phi == mpf(tphi)
if prec < 50:
assert mertens == mpf(tmertens)
assert twinprime == mpf(ttwinprime)
mp.dps = 15
assert pi >= -1
assert pi > 2
assert pi > 3
assert pi < 4
def test_exact_sqrts():
for i in range(20000):
assert sqrt(mpf(i*i)) == i
random.seed(1)
for prec in [100, 300, 1000, 10000]:
mp.dps = prec
for i in range(20):
A = random.randint(10**(prec//2-2), 10**(prec//2-1))
assert sqrt(mpf(A*A)) == A
mp.dps = 15
for i in range(100):
for a in [1, 8, 25, 112307]:
assert sqrt(mpf((a*a, 2*i))) == mpf((a, i))
assert sqrt(mpf((a*a, -2*i))) == mpf((a, -i))
def test_sqrt_rounding():
for i in [2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15]:
i = from_int(i)
for dps in [7, 15, 83, 106, 2000]:
mp.dps = dps
a = mpf_pow_int(mpf_sqrt(i, mp.prec, round_down), 2, mp.prec, round_down)
b = mpf_pow_int(mpf_sqrt(i, mp.prec, round_up), 2, mp.prec, round_up)
assert mpf_lt(a, i)
assert mpf_gt(b, i)
random.seed(1234)
prec = 100
for rnd in [round_down, round_nearest, round_ceiling]:
for i in range(100):
a = mpf_rand(prec)
b = mpf_mul(a, a)
assert mpf_sqrt(b, prec, rnd) == a
# Test some extreme cases
mp.dps = 100
a = mpf(9) + 1e-90
b = mpf(9) - 1e-90
mp.dps = 15
assert sqrt(a, rounding='d') == 3
assert sqrt(a, rounding='n') == 3
assert sqrt(a, rounding='u') > 3
assert sqrt(b, rounding='d') < 3
assert sqrt(b, rounding='n') == 3
assert sqrt(b, rounding='u') == 3
# A worst case, from the MPFR test suite
assert sqrt(mpf('7.0503726185518891')) == mpf('2.655253776675949')
def test_float_sqrt():
mp.dps = 15
# These should round identically
for x in [0, 1e-7, 0.1, 0.5, 1, 2, 3, 4, 5, 0.333, 76.19]:
assert sqrt(mpf(x)) == float(x)**0.5
assert sqrt(-1) == 1j
assert sqrt(-2).ae(cmath.sqrt(-2))
assert sqrt(-3).ae(cmath.sqrt(-3))
assert sqrt(-100).ae(cmath.sqrt(-100))
assert sqrt(1j).ae(cmath.sqrt(1j))
assert sqrt(-1j).ae(cmath.sqrt(-1j))
assert sqrt(math.pi + math.e*1j).ae(cmath.sqrt(math.pi + math.e*1j))
assert sqrt(math.pi - math.e*1j).ae(cmath.sqrt(math.pi - math.e*1j))
def test_hypot():
assert hypot(0, 0) == 0
assert hypot(0, 0.33) == mpf(0.33)
assert hypot(0.33, 0) == mpf(0.33)
assert hypot(-0.33, 0) == mpf(0.33)
assert hypot(3, 4) == mpf(5)
def test_exact_cbrt():
for i in range(0, 20000, 200):
assert cbrt(mpf(i*i*i)) == i
random.seed(1)
for prec in [100, 300, 1000, 10000]:
mp.dps = prec
A = random.randint(10**(prec//2-2), 10**(prec//2-1))
assert cbrt(mpf(A*A*A)) == A
mp.dps = 15
def test_exp():
assert exp(0) == 1
assert exp(10000).ae(mpf('8.8068182256629215873e4342'))
assert exp(-10000).ae(mpf('1.1354838653147360985e-4343'))
a = exp(mpf((1, 8198646019315405, -53, 53)))
assert(a.bc == bitcount(a.man))
mp.prec = 67
a = exp(mpf((1, 1781864658064754565, -60, 61)))
assert(a.bc == bitcount(a.man))
mp.prec = 53
assert exp(ln2 * 10).ae(1024)
assert exp(2+2j).ae(cmath.exp(2+2j))
def test_issue_73():
mp.dps = 512
a = exp(-1)
b = exp(1)
mp.dps = 15
assert (+a).ae(0.36787944117144233)
assert (+b).ae(2.7182818284590451)
def test_log():
mp.dps = 15
assert log(1) == 0
for x in [0.5, 1.5, 2.0, 3.0, 100, 10**50, 1e-50]:
assert log(x).ae(math.log(x))
assert log(x, x) == 1
assert log(1024, 2) == 10
assert log(10**1234, 10) == 1234
assert log(2+2j).ae(cmath.log(2+2j))
# Accuracy near 1
assert (log(0.6+0.8j).real*10**17).ae(2.2204460492503131)
assert (log(0.6-0.8j).real*10**17).ae(2.2204460492503131)
assert (log(0.8-0.6j).real*10**17).ae(2.2204460492503131)
assert (log(1+1e-8j).real*10**16).ae(0.5)
assert (log(1-1e-8j).real*10**16).ae(0.5)
assert (log(-1+1e-8j).real*10**16).ae(0.5)
assert (log(-1-1e-8j).real*10**16).ae(0.5)
assert (log(1j+1e-8).real*10**16).ae(0.5)
assert (log(1j-1e-8).real*10**16).ae(0.5)
assert (log(-1j+1e-8).real*10**16).ae(0.5)
assert (log(-1j-1e-8).real*10**16).ae(0.5)
assert (log(1+1e-40j).real*10**80).ae(0.5)
assert (log(1j+1e-40).real*10**80).ae(0.5)
# Huge
assert log(ldexp(1.234,10**20)).ae(log(2)*1e20)
assert log(ldexp(1.234,10**200)).ae(log(2)*1e200)
# Some special values
assert log(mpc(0,0)) == mpc(-inf,0)
assert isnan(log(mpc(nan,0)).real)
assert isnan(log(mpc(nan,0)).imag)
assert isnan(log(mpc(0,nan)).real)
assert isnan(log(mpc(0,nan)).imag)
assert isnan(log(mpc(nan,1)).real)
assert isnan(log(mpc(nan,1)).imag)
assert isnan(log(mpc(1,nan)).real)
assert isnan(log(mpc(1,nan)).imag)
def test_trig_hyperb_basic():
for x in (list(range(100)) + list(range(-100,0))):
t = x / 4.1
assert cos(mpf(t)).ae(math.cos(t))
assert sin(mpf(t)).ae(math.sin(t))
assert tan(mpf(t)).ae(math.tan(t))
assert cosh(mpf(t)).ae(math.cosh(t))
assert sinh(mpf(t)).ae(math.sinh(t))
assert tanh(mpf(t)).ae(math.tanh(t))
assert sin(1+1j).ae(cmath.sin(1+1j))
assert sin(-4-3.6j).ae(cmath.sin(-4-3.6j))
assert cos(1+1j).ae(cmath.cos(1+1j))
assert cos(-4-3.6j).ae(cmath.cos(-4-3.6j))
def test_degrees():
assert cos(0*degree) == 1
assert cos(90*degree).ae(0)
assert cos(180*degree).ae(-1)
assert cos(270*degree).ae(0)
assert cos(360*degree).ae(1)
assert sin(0*degree) == 0
assert sin(90*degree).ae(1)
assert sin(180*degree).ae(0)
assert sin(270*degree).ae(-1)
assert sin(360*degree).ae(0)
def random_complexes(N):
random.seed(1)
a = []
for i in range(N):
x1 = random.uniform(-10, 10)
y1 = random.uniform(-10, 10)
x2 = random.uniform(-10, 10)
y2 = random.uniform(-10, 10)
z1 = complex(x1, y1)
z2 = complex(x2, y2)
a.append((z1, z2))
return a
def test_complex_powers():
for dps in [15, 30, 100]:
# Check accuracy for complex square root
mp.dps = dps
a = mpc(1j)**0.5
assert a.real == a.imag == mpf(2)**0.5 / 2
mp.dps = 15
random.seed(1)
for (z1, z2) in random_complexes(100):
assert (mpc(z1)**mpc(z2)).ae(z1**z2, 1e-12)
assert (e**(-pi*1j)).ae(-1)
mp.dps = 50
assert (e**(-pi*1j)).ae(-1)
mp.dps = 15
def test_complex_sqrt_accuracy():
def test_mpc_sqrt(lst):
for a, b in lst:
z = mpc(a + j*b)
assert mpc_ae(sqrt(z*z), z)
z = mpc(-a + j*b)
assert mpc_ae(sqrt(z*z), -z)
z = mpc(a - j*b)
assert mpc_ae(sqrt(z*z), z)
z = mpc(-a - j*b)
assert mpc_ae(sqrt(z*z), -z)
random.seed(2)
N = 10
mp.dps = 30
dps = mp.dps
test_mpc_sqrt([(random.uniform(0, 10),random.uniform(0, 10)) for i in range(N)])
test_mpc_sqrt([(i + 0.1, (i + 0.2)*10**i) for i in range(N)])
mp.dps = 15
def test_atan():
mp.dps = 15
assert atan(-2.3).ae(math.atan(-2.3))
assert atan(1e-50) == 1e-50
assert atan(1e50).ae(pi/2)
assert atan(-1e-50) == -1e-50
assert atan(-1e50).ae(-pi/2)
assert atan(10**1000).ae(pi/2)
for dps in [25, 70, 100, 300, 1000]:
mp.dps = dps
assert (4*atan(1)).ae(pi)
mp.dps = 15
pi2 = pi/2
assert atan(mpc(inf,-1)).ae(pi2)
assert atan(mpc(inf,0)).ae(pi2)
assert atan(mpc(inf,1)).ae(pi2)
assert atan(mpc(1,inf)).ae(pi2)
assert atan(mpc(0,inf)).ae(pi2)
assert atan(mpc(-1,inf)).ae(-pi2)
assert atan(mpc(-inf,1)).ae(-pi2)
assert atan(mpc(-inf,0)).ae(-pi2)
assert atan(mpc(-inf,-1)).ae(-pi2)
assert atan(mpc(-1,-inf)).ae(-pi2)
assert atan(mpc(0,-inf)).ae(-pi2)
assert atan(mpc(1,-inf)).ae(pi2)
def test_atan2():
mp.dps = 15
assert atan2(1,1).ae(pi/4)
assert atan2(1,-1).ae(3*pi/4)
assert atan2(-1,-1).ae(-3*pi/4)
assert atan2(-1,1).ae(-pi/4)
assert atan2(-1,0).ae(-pi/2)
assert atan2(1,0).ae(pi/2)
assert atan2(0,0) == 0
assert atan2(inf,0).ae(pi/2)
assert atan2(-inf,0).ae(-pi/2)
assert isnan(atan2(inf,inf))
assert isnan(atan2(-inf,inf))
assert isnan(atan2(inf,-inf))
assert isnan(atan2(3,nan))
assert isnan(atan2(nan,3))
assert isnan(atan2(0,nan))
assert isnan(atan2(nan,0))
assert atan2(0,inf) == 0
assert atan2(0,-inf).ae(pi)
assert atan2(10,inf) == 0
assert atan2(-10,inf) == 0
assert atan2(-10,-inf).ae(-pi)
assert atan2(10,-inf).ae(pi)
assert atan2(inf,10).ae(pi/2)
assert atan2(inf,-10).ae(pi/2)
assert atan2(-inf,10).ae(-pi/2)
assert atan2(-inf,-10).ae(-pi/2)
def test_areal_inverses():
assert asin(mpf(0)) == 0
assert asinh(mpf(0)) == 0
assert acosh(mpf(1)) == 0
assert isinstance(asin(mpf(0.5)), mpf)
assert isinstance(asin(mpf(2.0)), mpc)
assert isinstance(acos(mpf(0.5)), mpf)
assert isinstance(acos(mpf(2.0)), mpc)
assert isinstance(atanh(mpf(0.1)), mpf)
assert isinstance(atanh(mpf(1.1)), mpc)
random.seed(1)
for i in range(50):
x = random.uniform(0, 1)
assert asin(mpf(x)).ae(math.asin(x))
assert acos(mpf(x)).ae(math.acos(x))
x = random.uniform(-10, 10)
assert asinh(mpf(x)).ae(cmath.asinh(x).real)
assert isinstance(asinh(mpf(x)), mpf)
x = random.uniform(1, 10)
assert acosh(mpf(x)).ae(cmath.acosh(x).real)
assert isinstance(acosh(mpf(x)), mpf)
x = random.uniform(-10, 0.999)
assert isinstance(acosh(mpf(x)), mpc)
x = random.uniform(-1, 1)
assert atanh(mpf(x)).ae(cmath.atanh(x).real)
assert isinstance(atanh(mpf(x)), mpf)
dps = mp.dps
mp.dps = 300
assert isinstance(asin(0.5), mpf)
mp.dps = 1000
assert asin(1).ae(pi/2)
assert asin(-1).ae(-pi/2)
mp.dps = dps
def test_invhyperb_inaccuracy():
mp.dps = 15
assert (asinh(1e-5)*10**5).ae(0.99999999998333333)
assert (asinh(1e-10)*10**10).ae(1)
assert (asinh(1e-50)*10**50).ae(1)
assert (asinh(-1e-5)*10**5).ae(-0.99999999998333333)
assert (asinh(-1e-10)*10**10).ae(-1)
assert (asinh(-1e-50)*10**50).ae(-1)
assert asinh(10**20).ae(46.744849040440862)
assert asinh(-10**20).ae(-46.744849040440862)
assert (tanh(1e-10)*10**10).ae(1)
assert (tanh(-1e-10)*10**10).ae(-1)
assert (atanh(1e-10)*10**10).ae(1)
assert (atanh(-1e-10)*10**10).ae(-1)
def test_complex_functions():
for x in (list(range(10)) + list(range(-10,0))):
for y in (list(range(10)) + list(range(-10,0))):
z = complex(x, y)/4.3 + 0.01j
assert exp(mpc(z)).ae(cmath.exp(z))
assert log(mpc(z)).ae(cmath.log(z))
assert cos(mpc(z)).ae(cmath.cos(z))
assert sin(mpc(z)).ae(cmath.sin(z))
assert tan(mpc(z)).ae(cmath.tan(z))
assert sinh(mpc(z)).ae(cmath.sinh(z))
assert cosh(mpc(z)).ae(cmath.cosh(z))
assert tanh(mpc(z)).ae(cmath.tanh(z))
def test_complex_inverse_functions():
mp.dps = 15
iv.dps = 15
for (z1, z2) in random_complexes(30):
# apparently cmath uses a different branch, so we
# can't use it for comparison
assert sinh(asinh(z1)).ae(z1)
#
assert acosh(z1).ae(cmath.acosh(z1))
assert atanh(z1).ae(cmath.atanh(z1))
assert atan(z1).ae(cmath.atan(z1))
# the reason we set a big eps here is that the cmath
# functions are inaccurate
assert asin(z1).ae(cmath.asin(z1), rel_eps=1e-12)
assert acos(z1).ae(cmath.acos(z1), rel_eps=1e-12)
one = mpf(1)
for i in range(-9, 10, 3):
for k in range(-9, 10, 3):
a = 0.9*j*10**k + 0.8*one*10**i
b = cos(acos(a))
assert b.ae(a)
b = sin(asin(a))
assert b.ae(a)
one = mpf(1)
err = 2*10**-15
for i in range(-9, 9, 3):
for k in range(-9, 9, 3):
a = -0.9*10**k + j*0.8*one*10**i
b = cosh(acosh(a))
assert b.ae(a, err)
b = sinh(asinh(a))
assert b.ae(a, err)
def test_reciprocal_functions():
assert sec(3).ae(-1.01010866590799375)
assert csc(3).ae(7.08616739573718592)
assert cot(3).ae(-7.01525255143453347)
assert sech(3).ae(0.0993279274194332078)
assert csch(3).ae(0.0998215696688227329)
assert coth(3).ae(1.00496982331368917)
assert asec(3).ae(1.23095941734077468)
assert acsc(3).ae(0.339836909454121937)
assert acot(3).ae(0.321750554396642193)
assert asech(0.5).ae(1.31695789692481671)
assert acsch(3).ae(0.327450150237258443)
assert acoth(3).ae(0.346573590279972655)
assert acot(0).ae(1.5707963267948966192)
assert acoth(0).ae(1.5707963267948966192j)
def test_ldexp():
mp.dps = 15
assert ldexp(mpf(2.5), 0) == 2.5
assert ldexp(mpf(2.5), -1) == 1.25
assert ldexp(mpf(2.5), 2) == 10
assert ldexp(mpf('inf'), 3) == mpf('inf')
def test_frexp():
mp.dps = 15
assert frexp(0) == (0.0, 0)
assert frexp(9) == (0.5625, 4)
assert frexp(1) == (0.5, 1)
assert frexp(0.2) == (0.8, -2)
assert frexp(1000) == (0.9765625, 10)
def test_aliases():
assert ln(7) == log(7)
assert log10(3.75) == log(3.75,10)
assert degrees(5.6) == 5.6 / degree
assert radians(5.6) == 5.6 * degree
assert power(-1,0.5) == j
assert fmod(25,7) == 4.0 and isinstance(fmod(25,7), mpf)
def test_arg_sign():
assert arg(3) == 0
assert arg(-3).ae(pi)
assert arg(j).ae(pi/2)
assert arg(-j).ae(-pi/2)
assert arg(0) == 0
assert isnan(atan2(3,nan))
assert isnan(atan2(nan,3))
assert isnan(atan2(0,nan))
assert isnan(atan2(nan,0))
assert isnan(atan2(nan,nan))
assert arg(inf) == 0
assert arg(-inf).ae(pi)
assert isnan(arg(nan))
#assert arg(inf*j).ae(pi/2)
assert sign(0) == 0
assert sign(3) == 1
assert sign(-3) == -1
assert sign(inf) == 1
assert sign(-inf) == -1
assert isnan(sign(nan))
assert sign(j) == j
assert sign(-3*j) == -j
assert sign(1+j).ae((1+j)/sqrt(2))
def test_misc_bugs():
# test that this doesn't raise an exception
mp.dps = 1000
log(1302)
mp.dps = 15
def test_arange():
assert arange(10) == [mpf('0.0'), mpf('1.0'), mpf('2.0'), mpf('3.0'),
mpf('4.0'), mpf('5.0'), mpf('6.0'), mpf('7.0'),
mpf('8.0'), mpf('9.0')]
assert arange(-5, 5) == [mpf('-5.0'), mpf('-4.0'), mpf('-3.0'),
mpf('-2.0'), mpf('-1.0'), mpf('0.0'),
mpf('1.0'), mpf('2.0'), mpf('3.0'), mpf('4.0')]
assert arange(0, 1, 0.1) == [mpf('0.0'), mpf('0.10000000000000001'),
mpf('0.20000000000000001'),
mpf('0.30000000000000004'),
mpf('0.40000000000000002'),
mpf('0.5'), mpf('0.60000000000000009'),
mpf('0.70000000000000007'),
mpf('0.80000000000000004'),
mpf('0.90000000000000002')]
assert arange(17, -9, -3) == [mpf('17.0'), mpf('14.0'), mpf('11.0'),
mpf('8.0'), mpf('5.0'), mpf('2.0'),
mpf('-1.0'), mpf('-4.0'), mpf('-7.0')]
assert arange(0.2, 0.1, -0.1) == [mpf('0.20000000000000001')]
assert arange(0) == []
assert arange(1000, -1) == []
assert arange(-1.23, 3.21, -0.0000001) == []
def test_linspace():
assert linspace(2, 9, 7) == [mpf('2.0'), mpf('3.166666666666667'),
mpf('4.3333333333333339'), mpf('5.5'), mpf('6.666666666666667'),
mpf('7.8333333333333339'), mpf('9.0')]
assert linspace(2, 9, 7, endpoint=0) == [mpf('2.0'), mpf('3.0'), mpf('4.0'),
mpf('5.0'), mpf('6.0'), mpf('7.0'), mpf('8.0')]
assert linspace(2, 7, 1) == [mpf(2)]
def test_float_cbrt():
mp.dps = 30
for a in arange(0,10,0.1):
assert cbrt(a*a*a).ae(a, eps)
assert cbrt(-1).ae(0.5 + j*sqrt(3)/2)
one_third = mpf(1)/3
for a in arange(0,10,2.7) + [0.1 + 10**5]:
a = mpc(a + 1.1j)
r1 = cbrt(a)
mp.dps += 10
r2 = pow(a, one_third)
mp.dps -= 10
assert r1.ae(r2, eps)
mp.dps = 100
for n in range(100, 301, 100):
w = 10**n + j*10**-3
z = w*w*w
r = cbrt(z)
assert mpc_ae(r, w, eps)
mp.dps = 15
def test_root():
mp.dps = 30
random.seed(1)
a = random.randint(0, 10000)
p = a*a*a
r = nthroot(mpf(p), 3)
assert r == a
for n in range(4, 10):
p = p*a
assert nthroot(mpf(p), n) == a
mp.dps = 40
for n in range(10, 5000, 100):
for a in [random.random()*10000, random.random()*10**100]:
r = nthroot(a, n)
r1 = pow(a, mpf(1)/n)
assert r.ae(r1)
r = nthroot(a, -n)
r1 = pow(a, -mpf(1)/n)
assert r.ae(r1)
# XXX: this is broken right now
# tests for nthroot rounding
for rnd in ['nearest', 'up', 'down']:
mp.rounding = rnd
for n in [-5, -3, 3, 5]:
prec = 50
for i in range(10):
mp.prec = prec
a = rand()
mp.prec = 2*prec
b = a**n
mp.prec = prec
r = nthroot(b, n)
assert r == a
mp.dps = 30
for n in range(3, 21):
a = (random.random() + j*random.random())
assert nthroot(a, n).ae(pow(a, mpf(1)/n))
assert mpc_ae(nthroot(a, n), pow(a, mpf(1)/n))
a = (random.random()*10**100 + j*random.random())
r = nthroot(a, n)
mp.dps += 4
r1 = pow(a, mpf(1)/n)
mp.dps -= 4
assert r.ae(r1)
assert mpc_ae(r, r1, eps)
r = nthroot(a, -n)
mp.dps += 4
r1 = pow(a, -mpf(1)/n)
mp.dps -= 4
assert r.ae(r1)
assert mpc_ae(r, r1, eps)
mp.dps = 15
assert nthroot(4, 1) == 4
assert nthroot(4, 0) == 1
assert nthroot(4, -1) == 0.25
assert nthroot(inf, 1) == inf
assert nthroot(inf, 2) == inf
assert nthroot(inf, 3) == inf
assert nthroot(inf, -1) == 0
assert nthroot(inf, -2) == 0
assert nthroot(inf, -3) == 0
assert nthroot(j, 1) == j
assert nthroot(j, 0) == 1
assert nthroot(j, -1) == -j
assert isnan(nthroot(nan, 1))
assert isnan(nthroot(nan, 0))
assert isnan(nthroot(nan, -1))
assert isnan(nthroot(inf, 0))
assert root(2,3) == nthroot(2,3)
assert root(16,4,0) == 2
assert root(16,4,1) == 2j
assert root(16,4,2) == -2
assert root(16,4,3) == -2j
assert root(16,4,4) == 2
assert root(-125,3,1) == -5
def test_issue_136():
for dps in [20, 80]:
mp.dps = dps
r = nthroot(mpf('-1e-20'), 4)
assert r.ae(mpf(10)**(-5) * (1 + j) * mpf(2)**(-0.5))
mp.dps = 80
assert nthroot('-1e-3', 4).ae(mpf(10)**(-3./4) * (1 + j)/sqrt(2))
assert nthroot('-1e-6', 4).ae((1 + j)/(10 * sqrt(20)))
# Check that this doesn't take eternity to compute
mp.dps = 20
assert nthroot('-1e100000000', 4).ae((1+j)*mpf('1e25000000')/sqrt(2))
mp.dps = 15
def test_mpcfun_real_imag():
mp.dps = 15
x = mpf(0.3)
y = mpf(0.4)
assert exp(mpc(x,0)) == exp(x)
assert exp(mpc(0,y)) == mpc(cos(y),sin(y))
assert cos(mpc(x,0)) == cos(x)
assert sin(mpc(x,0)) == sin(x)
assert cos(mpc(0,y)) == cosh(y)
assert sin(mpc(0,y)) == mpc(0,sinh(y))
assert cospi(mpc(x,0)) == cospi(x)
assert sinpi(mpc(x,0)) == sinpi(x)
assert cospi(mpc(0,y)).ae(cosh(pi*y))
assert sinpi(mpc(0,y)).ae(mpc(0,sinh(pi*y)))
c, s = cospi_sinpi(mpc(x,0))
assert c == cospi(x)
assert s == sinpi(x)
c, s = cospi_sinpi(mpc(0,y))
assert c.ae(cosh(pi*y))
assert s.ae(mpc(0,sinh(pi*y)))
c, s = cos_sin(mpc(x,0))
assert c == cos(x)
assert s == sin(x)
c, s = cos_sin(mpc(0,y))
assert c == cosh(y)
assert s == mpc(0,sinh(y))
def test_perturbation_rounding():
mp.dps = 100
a = pi/10**50
b = -pi/10**50
c = 1 + a
d = 1 + b
mp.dps = 15
assert exp(a) == 1
assert exp(a, rounding='c') > 1
assert exp(b, rounding='c') == 1
assert exp(a, rounding='f') == 1
assert exp(b, rounding='f') < 1
assert cos(a) == 1
assert cos(a, rounding='c') == 1
assert cos(b, rounding='c') == 1
assert cos(a, rounding='f') < 1
assert cos(b, rounding='f') < 1
for f in [sin, atan, asinh, tanh]:
assert f(a) == +a
assert f(a, rounding='c') > a
assert f(a, rounding='f') < a
assert f(b) == +b
assert f(b, rounding='c') > b
assert f(b, rounding='f') < b
for f in [asin, tan, sinh, atanh]:
assert f(a) == +a
assert f(b) == +b
assert f(a, rounding='c') > a
assert f(b, rounding='c') > b
assert f(a, rounding='f') < a
assert f(b, rounding='f') < b
assert ln(c) == +a
assert ln(d) == +b
assert ln(c, rounding='c') > a
assert ln(c, rounding='f') < a
assert ln(d, rounding='c') > b
assert ln(d, rounding='f') < b
assert cosh(a) == 1
assert cosh(b) == 1
assert cosh(a, rounding='c') > 1
assert cosh(b, rounding='c') > 1
assert cosh(a, rounding='f') == 1
assert cosh(b, rounding='f') == 1
def test_integer_parts():
assert floor(3.2) == 3
assert ceil(3.2) == 4
assert floor(3.2+5j) == 3+5j
assert ceil(3.2+5j) == 4+5j
def test_complex_parts():
assert fabs('3') == 3
assert fabs(3+4j) == 5
assert re(3) == 3
assert re(1+4j) == 1
assert im(3) == 0
assert im(1+4j) == 4
assert conj(3) == 3
assert conj(3+4j) == 3-4j
assert mpf(3).conjugate() == 3
def test_cospi_sinpi():
assert sinpi(0) == 0
assert sinpi(0.5) == 1
assert sinpi(1) == 0
assert sinpi(1.5) == -1
assert sinpi(2) == 0
assert sinpi(2.5) == 1
assert sinpi(-0.5) == -1
assert cospi(0) == 1
assert cospi(0.5) == 0
assert cospi(1) == -1
assert cospi(1.5) == 0
assert cospi(2) == 1
assert cospi(2.5) == 0
assert cospi(-0.5) == 0
assert cospi(100000000000.25).ae(sqrt(2)/2)
a = cospi(2+3j)
assert a.real.ae(cos((2+3j)*pi).real)
assert a.imag == 0
b = sinpi(2+3j)
assert b.imag.ae(sin((2+3j)*pi).imag)
assert b.real == 0
mp.dps = 35
x1 = mpf(10000) - mpf('1e-15')
x2 = mpf(10000) + mpf('1e-15')
x3 = mpf(10000.5) - mpf('1e-15')
x4 = mpf(10000.5) + mpf('1e-15')
x5 = mpf(10001) - mpf('1e-15')
x6 = mpf(10001) + mpf('1e-15')
x7 = mpf(10001.5) - mpf('1e-15')
x8 = mpf(10001.5) + mpf('1e-15')
mp.dps = 15
M = 10**15
assert (sinpi(x1)*M).ae(-pi)
assert (sinpi(x2)*M).ae(pi)
assert (cospi(x3)*M).ae(pi)
assert (cospi(x4)*M).ae(-pi)
assert (sinpi(x5)*M).ae(pi)
assert (sinpi(x6)*M).ae(-pi)
assert (cospi(x7)*M).ae(-pi)
assert (cospi(x8)*M).ae(pi)
assert 0.999 < cospi(x1, rounding='d') < 1
assert 0.999 < cospi(x2, rounding='d') < 1
assert 0.999 < sinpi(x3, rounding='d') < 1
assert 0.999 < sinpi(x4, rounding='d') < 1
assert -1 < cospi(x5, rounding='d') < -0.999
assert -1 < cospi(x6, rounding='d') < -0.999
assert -1 < sinpi(x7, rounding='d') < -0.999
assert -1 < sinpi(x8, rounding='d') < -0.999
assert (sinpi(1e-15)*M).ae(pi)
assert (sinpi(-1e-15)*M).ae(-pi)
assert cospi(1e-15) == 1
assert cospi(1e-15, rounding='d') < 1
def test_expj():
assert expj(0) == 1
assert expj(1).ae(exp(j))
assert expj(j).ae(exp(-1))
assert expj(1+j).ae(exp(j*(1+j)))
assert expjpi(0) == 1
assert expjpi(1).ae(exp(j*pi))
assert expjpi(j).ae(exp(-pi))
assert expjpi(1+j).ae(exp(j*pi*(1+j)))
assert expjpi(-10**15 * j).ae('2.22579818340535731e+1364376353841841')
def test_sinc():
assert sinc(0) == sincpi(0) == 1
assert sinc(inf) == sincpi(inf) == 0
assert sinc(-inf) == sincpi(-inf) == 0
assert sinc(2).ae(0.45464871341284084770)
assert sinc(2+3j).ae(0.4463290318402435457-2.7539470277436474940j)
assert sincpi(2) == 0
assert sincpi(1.5).ae(-0.212206590789193781)
def test_fibonacci():
mp.dps = 15
assert [fibonacci(n) for n in range(-5, 10)] == \
[5, -3, 2, -1, 1, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
assert fib(2.5).ae(1.4893065462657091)
assert fib(3+4j).ae(-5248.51130728372 - 14195.962288353j)
assert fib(1000).ae(4.3466557686937455e+208)
assert str(fib(10**100)) == '6.24499112864607e+2089876402499787337692720892375554168224592399182109535392875613974104853496745963277658556235103534'
mp.dps = 2100
a = fib(10000)
assert a % 10**10 == 9947366875
mp.dps = 15
assert fibonacci(inf) == inf
assert fib(3+0j) == 2
def test_call_with_dps():
mp.dps = 15
assert abs(exp(1, dps=30)-e(dps=35)) < 1e-29
def test_tanh():
mp.dps = 15
assert tanh(0) == 0
assert tanh(inf) == 1
assert tanh(-inf) == -1
assert isnan(tanh(nan))
assert tanh(mpc('inf', '0')) == 1
def test_atanh():
mp.dps = 15
assert atanh(0) == 0
assert atanh(0.5).ae(0.54930614433405484570)
assert atanh(-0.5).ae(-0.54930614433405484570)
assert atanh(1) == inf
assert atanh(-1) == -inf
assert isnan(atanh(nan))
assert isinstance(atanh(1), mpf)
assert isinstance(atanh(-1), mpf)
# Limits at infinity
jpi2 = j*pi/2
assert atanh(inf).ae(-jpi2)
assert atanh(-inf).ae(jpi2)
assert atanh(mpc(inf,-1)).ae(-jpi2)
assert atanh(mpc(inf,0)).ae(-jpi2)
assert atanh(mpc(inf,1)).ae(jpi2)
assert atanh(mpc(1,inf)).ae(jpi2)
assert atanh(mpc(0,inf)).ae(jpi2)
assert atanh(mpc(-1,inf)).ae(jpi2)
assert atanh(mpc(-inf,1)).ae(jpi2)
assert atanh(mpc(-inf,0)).ae(jpi2)
assert atanh(mpc(-inf,-1)).ae(-jpi2)
assert atanh(mpc(-1,-inf)).ae(-jpi2)
assert atanh(mpc(0,-inf)).ae(-jpi2)
assert atanh(mpc(1,-inf)).ae(-jpi2)
def test_expm1():
mp.dps = 15
assert expm1(0) == 0
assert expm1(3).ae(exp(3)-1)
assert expm1(inf) == inf
assert expm1(1e-50).ae(1e-50)
assert (expm1(1e-10)*1e10).ae(1.00000000005)
def test_log1p():
mp.dps = 15
assert log1p(0) == 0
assert log1p(3).ae(log(1+3))
assert log1p(inf) == inf
assert log1p(1e-50).ae(1e-50)
assert (log1p(1e-10)*1e10).ae(0.99999999995)
def test_powm1():
mp.dps = 15
assert powm1(2,3) == 7
assert powm1(-1,2) == 0
assert powm1(-1,0) == 0
assert powm1(-2,0) == 0
assert powm1(3+4j,0) == 0
assert powm1(0,1) == -1
assert powm1(0,0) == 0
assert powm1(1,0) == 0
assert powm1(1,2) == 0
assert powm1(1,3+4j) == 0
assert powm1(1,5) == 0
assert powm1(j,4) == 0
assert powm1(-j,4) == 0
assert (powm1(2,1e-100)*1e100).ae(ln2)
assert powm1(2,'1e-100000000000') != 0
assert (powm1(fadd(1,1e-100,exact=True), 5)*1e100).ae(5)
def test_unitroots():
assert unitroots(1) == [1]
assert unitroots(2) == [1, -1]
a, b, c = unitroots(3)
assert a == 1
assert b.ae(-0.5 + 0.86602540378443864676j)
assert c.ae(-0.5 - 0.86602540378443864676j)
assert unitroots(1, primitive=True) == [1]
assert unitroots(2, primitive=True) == [-1]
assert unitroots(3, primitive=True) == unitroots(3)[1:]
assert unitroots(4, primitive=True) == [j, -j]
assert len(unitroots(17, primitive=True)) == 16
assert len(unitroots(16, primitive=True)) == 8
def test_cyclotomic():
mp.dps = 15
assert [cyclotomic(n,1) for n in range(31)] == [1,0,2,3,2,5,1,7,2,3,1,11,1,13,1,1,2,17,1,19,1,1,1,23,1,5,1,3,1,29,1]
assert [cyclotomic(n,-1) for n in range(31)] == [1,-2,0,1,2,1,3,1,2,1,5,1,1,1,7,1,2,1,3,1,1,1,11,1,1,1,13,1,1,1,1]
assert [cyclotomic(n,j) for n in range(21)] == [1,-1+j,1+j,j,0,1,-j,j,2,-j,1,j,3,1,-j,1,2,1,j,j,5]
assert [cyclotomic(n,-j) for n in range(21)] == [1,-1-j,1-j,-j,0,1,j,-j,2,j,1,-j,3,1,j,1,2,1,-j,-j,5]
assert cyclotomic(1624,j) == 1
assert cyclotomic(33600,j) == 1
u = sqrt(j, prec=500)
assert cyclotomic(8, u).ae(0)
assert cyclotomic(30, u).ae(5.8284271247461900976)
assert cyclotomic(2040, u).ae(1)
assert cyclotomic(0,2.5) == 1
assert cyclotomic(1,2.5) == 2.5-1
assert cyclotomic(2,2.5) == 2.5+1
assert cyclotomic(3,2.5) == 2.5**2 + 2.5 + 1
assert cyclotomic(7,2.5) == 406.234375

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,698 @@
from mpmath import *
from mpmath.libmp import round_up, from_float, mpf_zeta_int
def test_zeta_int_bug():
assert mpf_zeta_int(0, 10) == from_float(-0.5)
def test_bernoulli():
assert bernfrac(0) == (1,1)
assert bernfrac(1) == (-1,2)
assert bernfrac(2) == (1,6)
assert bernfrac(3) == (0,1)
assert bernfrac(4) == (-1,30)
assert bernfrac(5) == (0,1)
assert bernfrac(6) == (1,42)
assert bernfrac(8) == (-1,30)
assert bernfrac(10) == (5,66)
assert bernfrac(12) == (-691,2730)
assert bernfrac(18) == (43867,798)
p, q = bernfrac(228)
assert p % 10**10 == 164918161
assert q == 625170
p, q = bernfrac(1000)
assert p % 10**10 == 7950421099
assert q == 342999030
mp.dps = 15
assert bernoulli(0) == 1
assert bernoulli(1) == -0.5
assert bernoulli(2).ae(1./6)
assert bernoulli(3) == 0
assert bernoulli(4).ae(-1./30)
assert bernoulli(5) == 0
assert bernoulli(6).ae(1./42)
assert str(bernoulli(10)) == '0.0757575757575758'
assert str(bernoulli(234)) == '7.62772793964344e+267'
assert str(bernoulli(10**5)) == '-5.82229431461335e+376755'
assert str(bernoulli(10**8+2)) == '1.19570355039953e+676752584'
mp.dps = 50
assert str(bernoulli(10)) == '0.075757575757575757575757575757575757575757575757576'
assert str(bernoulli(234)) == '7.6277279396434392486994969020496121553385863373331e+267'
assert str(bernoulli(10**5)) == '-5.8222943146133508236497045360612887555320691004308e+376755'
assert str(bernoulli(10**8+2)) == '1.1957035503995297272263047884604346914602088317782e+676752584'
mp.dps = 1000
assert bernoulli(10).ae(mpf(5)/66)
mp.dps = 50000
assert bernoulli(10).ae(mpf(5)/66)
mp.dps = 15
def test_bernpoly_eulerpoly():
mp.dps = 15
assert bernpoly(0,-1).ae(1)
assert bernpoly(0,0).ae(1)
assert bernpoly(0,'1/2').ae(1)
assert bernpoly(0,'3/4').ae(1)
assert bernpoly(0,1).ae(1)
assert bernpoly(0,2).ae(1)
assert bernpoly(1,-1).ae('-3/2')
assert bernpoly(1,0).ae('-1/2')
assert bernpoly(1,'1/2').ae(0)
assert bernpoly(1,'3/4').ae('1/4')
assert bernpoly(1,1).ae('1/2')
assert bernpoly(1,2).ae('3/2')
assert bernpoly(2,-1).ae('13/6')
assert bernpoly(2,0).ae('1/6')
assert bernpoly(2,'1/2').ae('-1/12')
assert bernpoly(2,'3/4').ae('-1/48')
assert bernpoly(2,1).ae('1/6')
assert bernpoly(2,2).ae('13/6')
assert bernpoly(3,-1).ae(-3)
assert bernpoly(3,0).ae(0)
assert bernpoly(3,'1/2').ae(0)
assert bernpoly(3,'3/4').ae('-3/64')
assert bernpoly(3,1).ae(0)
assert bernpoly(3,2).ae(3)
assert bernpoly(4,-1).ae('119/30')
assert bernpoly(4,0).ae('-1/30')
assert bernpoly(4,'1/2').ae('7/240')
assert bernpoly(4,'3/4').ae('7/3840')
assert bernpoly(4,1).ae('-1/30')
assert bernpoly(4,2).ae('119/30')
assert bernpoly(5,-1).ae(-5)
assert bernpoly(5,0).ae(0)
assert bernpoly(5,'1/2').ae(0)
assert bernpoly(5,'3/4').ae('25/1024')
assert bernpoly(5,1).ae(0)
assert bernpoly(5,2).ae(5)
assert bernpoly(10,-1).ae('665/66')
assert bernpoly(10,0).ae('5/66')
assert bernpoly(10,'1/2').ae('-2555/33792')
assert bernpoly(10,'3/4').ae('-2555/34603008')
assert bernpoly(10,1).ae('5/66')
assert bernpoly(10,2).ae('665/66')
assert bernpoly(11,-1).ae(-11)
assert bernpoly(11,0).ae(0)
assert bernpoly(11,'1/2').ae(0)
assert bernpoly(11,'3/4').ae('-555731/4194304')
assert bernpoly(11,1).ae(0)
assert bernpoly(11,2).ae(11)
assert eulerpoly(0,-1).ae(1)
assert eulerpoly(0,0).ae(1)
assert eulerpoly(0,'1/2').ae(1)
assert eulerpoly(0,'3/4').ae(1)
assert eulerpoly(0,1).ae(1)
assert eulerpoly(0,2).ae(1)
assert eulerpoly(1,-1).ae('-3/2')
assert eulerpoly(1,0).ae('-1/2')
assert eulerpoly(1,'1/2').ae(0)
assert eulerpoly(1,'3/4').ae('1/4')
assert eulerpoly(1,1).ae('1/2')
assert eulerpoly(1,2).ae('3/2')
assert eulerpoly(2,-1).ae(2)
assert eulerpoly(2,0).ae(0)
assert eulerpoly(2,'1/2').ae('-1/4')
assert eulerpoly(2,'3/4').ae('-3/16')
assert eulerpoly(2,1).ae(0)
assert eulerpoly(2,2).ae(2)
assert eulerpoly(3,-1).ae('-9/4')
assert eulerpoly(3,0).ae('1/4')
assert eulerpoly(3,'1/2').ae(0)
assert eulerpoly(3,'3/4').ae('-11/64')
assert eulerpoly(3,1).ae('-1/4')
assert eulerpoly(3,2).ae('9/4')
assert eulerpoly(4,-1).ae(2)
assert eulerpoly(4,0).ae(0)
assert eulerpoly(4,'1/2').ae('5/16')
assert eulerpoly(4,'3/4').ae('57/256')
assert eulerpoly(4,1).ae(0)
assert eulerpoly(4,2).ae(2)
assert eulerpoly(5,-1).ae('-3/2')
assert eulerpoly(5,0).ae('-1/2')
assert eulerpoly(5,'1/2').ae(0)
assert eulerpoly(5,'3/4').ae('361/1024')
assert eulerpoly(5,1).ae('1/2')
assert eulerpoly(5,2).ae('3/2')
assert eulerpoly(10,-1).ae(2)
assert eulerpoly(10,0).ae(0)
assert eulerpoly(10,'1/2').ae('-50521/1024')
assert eulerpoly(10,'3/4').ae('-36581523/1048576')
assert eulerpoly(10,1).ae(0)
assert eulerpoly(10,2).ae(2)
assert eulerpoly(11,-1).ae('-699/4')
assert eulerpoly(11,0).ae('691/4')
assert eulerpoly(11,'1/2').ae(0)
assert eulerpoly(11,'3/4').ae('-512343611/4194304')
assert eulerpoly(11,1).ae('-691/4')
assert eulerpoly(11,2).ae('699/4')
# Potential accuracy issues
assert bernpoly(10000,10000).ae('5.8196915936323387117e+39999')
assert bernpoly(200,17.5).ae(3.8048418524583064909e244)
assert eulerpoly(200,17.5).ae(-3.7309911582655785929e275)
def test_gamma():
mp.dps = 15
assert gamma(0.25).ae(3.6256099082219083119)
assert gamma(0.0001).ae(9999.4228832316241908)
assert gamma(300).ae('1.0201917073881354535e612')
assert gamma(-0.5).ae(-3.5449077018110320546)
assert gamma(-7.43).ae(0.00026524416464197007186)
#assert gamma(Rational(1,2)) == gamma(0.5)
#assert gamma(Rational(-7,3)).ae(gamma(mpf(-7)/3))
assert gamma(1+1j).ae(0.49801566811835604271 - 0.15494982830181068512j)
assert gamma(-1+0.01j).ae(-0.422733904013474115 + 99.985883082635367436j)
assert gamma(20+30j).ae(-1453876687.5534810 + 1163777777.8031573j)
# Should always give exact factorials when they can
# be represented as mpfs under the current working precision
fact = 1
for i in range(1, 18):
assert gamma(i) == fact
fact *= i
for dps in [170, 600]:
fact = 1
mp.dps = dps
for i in range(1, 105):
assert gamma(i) == fact
fact *= i
mp.dps = 100
assert gamma(0.5).ae(sqrt(pi))
mp.dps = 15
assert factorial(0) == fac(0) == 1
assert factorial(3) == 6
assert isnan(gamma(nan))
assert gamma(1100).ae('4.8579168073569433667e2866')
assert rgamma(0) == 0
assert rgamma(-1) == 0
assert rgamma(2) == 1.0
assert rgamma(3) == 0.5
assert loggamma(2+8j).ae(-8.5205176753667636926 + 10.8569497125597429366j)
assert loggamma('1e10000').ae('2.302485092994045684017991e10004')
assert loggamma('1e10000j').ae(mpc('-1.570796326794896619231322e10000','2.302485092994045684017991e10004'))
def test_fac2():
mp.dps = 15
assert [fac2(n) for n in range(10)] == [1,1,2,3,8,15,48,105,384,945]
assert fac2(-5).ae(1./3)
assert fac2(-11).ae(-1./945)
assert fac2(50).ae(5.20469842636666623e32)
assert fac2(0.5+0.75j).ae(0.81546769394688069176-0.34901016085573266889j)
assert fac2(inf) == inf
assert isnan(fac2(-inf))
def test_gamma_quotients():
mp.dps = 15
h = 1e-8
ep = 1e-4
G = gamma
assert gammaprod([-1],[-3,-4]) == 0
assert gammaprod([-1,0],[-5]) == inf
assert abs(gammaprod([-1],[-2]) - G(-1+h)/G(-2+h)) < 1e-4
assert abs(gammaprod([-4,-3],[-2,0]) - G(-4+h)*G(-3+h)/G(-2+h)/G(0+h)) < 1e-4
assert rf(3,0) == 1
assert rf(2.5,1) == 2.5
assert rf(-5,2) == 20
assert rf(j,j).ae(gamma(2*j)/gamma(j))
assert rf('-255.5815971722918','-0.5119253100282322').ae('-0.1952720278805729485') # issue 421
assert ff(-2,0) == 1
assert ff(-2,1) == -2
assert ff(4,3) == 24
assert ff(3,4) == 0
assert binomial(0,0) == 1
assert binomial(1,0) == 1
assert binomial(0,-1) == 0
assert binomial(3,2) == 3
assert binomial(5,2) == 10
assert binomial(5,3) == 10
assert binomial(5,5) == 1
assert binomial(-1,0) == 1
assert binomial(-2,-4) == 3
assert binomial(4.5, 1.5) == 6.5625
assert binomial(1100,1) == 1100
assert binomial(1100,2) == 604450
assert beta(1,1) == 1
assert beta(0,0) == inf
assert beta(3,0) == inf
assert beta(-1,-1) == inf
assert beta(1.5,1).ae(2/3.)
assert beta(1.5,2.5).ae(pi/16)
assert (10**15*beta(10,100)).ae(2.3455339739604649879)
assert beta(inf,inf) == 0
assert isnan(beta(-inf,inf))
assert isnan(beta(-3,inf))
assert isnan(beta(0,inf))
assert beta(inf,0.5) == beta(0.5,inf) == 0
assert beta(inf,-1.5) == inf
assert beta(inf,-0.5) == -inf
assert beta(1+2j,-1-j/2).ae(1.16396542451069943086+0.08511695947832914640j)
assert beta(-0.5,0.5) == 0
assert beta(-3,3).ae(-1/3.)
assert beta('-255.5815971722918','-0.5119253100282322').ae('18.157330562703710339') # issue 421
def test_zeta():
mp.dps = 15
assert zeta(2).ae(pi**2 / 6)
assert zeta(2.0).ae(pi**2 / 6)
assert zeta(mpc(2)).ae(pi**2 / 6)
assert zeta(100).ae(1)
assert zeta(0).ae(-0.5)
assert zeta(0.5).ae(-1.46035450880958681)
assert zeta(-1).ae(-mpf(1)/12)
assert zeta(-2) == 0
assert zeta(-3).ae(mpf(1)/120)
assert zeta(-4) == 0
assert zeta(-100) == 0
assert isnan(zeta(nan))
assert zeta(1e-30).ae(-0.5)
assert zeta(-1e-30).ae(-0.5)
# Zeros in the critical strip
assert zeta(mpc(0.5, 14.1347251417346937904)).ae(0)
assert zeta(mpc(0.5, 21.0220396387715549926)).ae(0)
assert zeta(mpc(0.5, 25.0108575801456887632)).ae(0)
assert zeta(mpc(1e-30,1e-40)).ae(-0.5)
assert zeta(mpc(-1e-30,1e-40)).ae(-0.5)
mp.dps = 50
im = '236.5242296658162058024755079556629786895294952121891237'
assert zeta(mpc(0.5, im)).ae(0, 1e-46)
mp.dps = 15
# Complex reflection formula
assert (zeta(-60+3j) / 10**34).ae(8.6270183987866146+15.337398548226238j)
# issue #358
assert zeta(0,0.5) == 0
assert zeta(0,0) == 0.5
assert zeta(0,0.5,1).ae(-0.34657359027997265)
# see issue #390
assert zeta(-1.5,0.5j).ae(-0.13671400162512768475 + 0.11411333638426559139j)
def test_altzeta():
mp.dps = 15
assert altzeta(-2) == 0
assert altzeta(-4) == 0
assert altzeta(-100) == 0
assert altzeta(0) == 0.5
assert altzeta(-1) == 0.25
assert altzeta(-3) == -0.125
assert altzeta(-5) == 0.25
assert altzeta(-21) == 1180529130.25
assert altzeta(1).ae(log(2))
assert altzeta(2).ae(pi**2/12)
assert altzeta(10).ae(73*pi**10/6842880)
assert altzeta(50) < 1
assert altzeta(60, rounding='d') < 1
assert altzeta(60, rounding='u') == 1
assert altzeta(10000, rounding='d') < 1
assert altzeta(10000, rounding='u') == 1
assert altzeta(3+0j) == altzeta(3)
s = 3+4j
assert altzeta(s).ae((1-2**(1-s))*zeta(s))
s = -3+4j
assert altzeta(s).ae((1-2**(1-s))*zeta(s))
assert altzeta(-100.5).ae(4.58595480083585913e+108)
assert altzeta(1.3).ae(0.73821404216623045)
assert altzeta(1e-30).ae(0.5)
assert altzeta(-1e-30).ae(0.5)
assert altzeta(mpc(1e-30,1e-40)).ae(0.5)
assert altzeta(mpc(-1e-30,1e-40)).ae(0.5)
def test_zeta_huge():
mp.dps = 15
assert zeta(inf) == 1
mp.dps = 50
assert zeta(100).ae('1.0000000000000000000000000000007888609052210118073522')
assert zeta(40*pi).ae('1.0000000000000000000000000000000000000148407238666182')
mp.dps = 10000
v = zeta(33000)
mp.dps = 15
assert str(v-1) == '1.02363019598118e-9934'
assert zeta(pi*1000, rounding=round_up) > 1
assert zeta(3000, rounding=round_up) > 1
assert zeta(pi*1000) == 1
assert zeta(3000) == 1
def test_zeta_negative():
mp.dps = 150
a = -pi*10**40
mp.dps = 15
assert str(zeta(a)) == '2.55880492708712e+1233536161668617575553892558646631323374078'
mp.dps = 50
assert str(zeta(a)) == '2.5588049270871154960875033337384432038436330847333e+1233536161668617575553892558646631323374078'
mp.dps = 15
def test_polygamma():
mp.dps = 15
psi0 = lambda z: psi(0,z)
psi1 = lambda z: psi(1,z)
assert psi0(3) == psi(0,3) == digamma(3)
#assert psi2(3) == psi(2,3) == tetragamma(3)
#assert psi3(3) == psi(3,3) == pentagamma(3)
assert psi0(pi).ae(0.97721330794200673)
assert psi0(-pi).ae(7.8859523853854902)
assert psi0(-pi+1).ae(7.5676424992016996)
assert psi0(pi+j).ae(1.04224048313859376 + 0.35853686544063749j)
assert psi0(-pi-j).ae(1.3404026194821986 - 2.8824392476809402j)
assert findroot(psi0, 1).ae(1.4616321449683622)
assert psi0(1e-10).ae(-10000000000.57722)
assert psi0(1e-40).ae(-1.000000000000000e+40)
assert psi0(1e-10+1e-10j).ae(-5000000000.577215 + 5000000000.000000j)
assert psi0(1e-40+1e-40j).ae(-5.000000000000000e+39 + 5.000000000000000e+39j)
assert psi0(inf) == inf
assert psi1(inf) == 0
assert psi(2,inf) == 0
assert psi1(pi).ae(0.37424376965420049)
assert psi1(-pi).ae(53.030438740085385)
assert psi1(pi+j).ae(0.32935710377142464 - 0.12222163911221135j)
assert psi1(-pi-j).ae(-0.30065008356019703 + 0.01149892486928227j)
assert (10**6*psi(4,1+10*pi*j)).ae(-6.1491803479004446 - 0.3921316371664063j)
assert psi0(1+10*pi*j).ae(3.4473994217222650 + 1.5548808324857071j)
assert isnan(psi0(nan))
assert isnan(psi0(-inf))
assert psi0(-100.5).ae(4.615124601338064)
assert psi0(3+0j).ae(psi0(3))
assert psi0(-100+3j).ae(4.6106071768714086321+3.1117510556817394626j)
assert isnan(psi(2,mpc(0,inf)))
assert isnan(psi(2,mpc(0,nan)))
assert isnan(psi(2,mpc(0,-inf)))
assert isnan(psi(2,mpc(1,inf)))
assert isnan(psi(2,mpc(1,nan)))
assert isnan(psi(2,mpc(1,-inf)))
assert isnan(psi(2,mpc(inf,inf)))
assert isnan(psi(2,mpc(nan,nan)))
assert isnan(psi(2,mpc(-inf,-inf)))
mp.dps = 30
# issue #534
assert digamma(-0.75+1j).ae(mpc('0.46317279488182026118963809283042317', '2.4821070143037957102007677817351115'))
mp.dps = 15
def test_polygamma_high_prec():
mp.dps = 100
assert str(psi(0,pi)) == "0.9772133079420067332920694864061823436408346099943256380095232865318105924777141317302075654362928734"
assert str(psi(10,pi)) == "-12.98876181434889529310283769414222588307175962213707170773803550518307617769657562747174101900659238"
def test_polygamma_identities():
mp.dps = 15
psi0 = lambda z: psi(0,z)
psi1 = lambda z: psi(1,z)
psi2 = lambda z: psi(2,z)
assert psi0(0.5).ae(-euler-2*log(2))
assert psi0(1).ae(-euler)
assert psi1(0.5).ae(0.5*pi**2)
assert psi1(1).ae(pi**2/6)
assert psi1(0.25).ae(pi**2 + 8*catalan)
assert psi2(1).ae(-2*apery)
mp.dps = 20
u = -182*apery+4*sqrt(3)*pi**3
mp.dps = 15
assert psi(2,5/6.).ae(u)
assert psi(3,0.5).ae(pi**4)
def test_foxtrot_identity():
# A test of the complex digamma function.
# See http://mathworld.wolfram.com/FoxTrotSeries.html and
# http://mathworld.wolfram.com/DigammaFunction.html
psi0 = lambda z: psi(0,z)
mp.dps = 50
a = (-1)**fraction(1,3)
b = (-1)**fraction(2,3)
x = -psi0(0.5*a) - psi0(-0.5*b) + psi0(0.5*(1+a)) + psi0(0.5*(1-b))
y = 2*pi*sech(0.5*sqrt(3)*pi)
assert x.ae(y)
mp.dps = 15
def test_polygamma_high_order():
mp.dps = 100
assert str(psi(50, pi)) == "-1344100348958402765749252447726432491812.641985273160531055707095989227897753035823152397679626136483"
assert str(psi(50, pi + 14*e)) == "-0.00000000000000000189793739550804321623512073101895801993019919886375952881053090844591920308111549337295143780341396"
assert str(psi(50, pi + 14*e*j)) == ("(-0.0000000000000000522516941152169248975225472155683565752375889510631513244785"
"9377385233700094871256507814151956624433 - 0.00000000000000001813157041407010184"
"702414110218205348527862196327980417757665282244728963891298080199341480881811613j)")
mp.dps = 15
assert str(psi(50, pi)) == "-1.34410034895841e+39"
assert str(psi(50, pi + 14*e)) == "-1.89793739550804e-18"
assert str(psi(50, pi + 14*e*j)) == "(-5.2251694115217e-17 - 1.81315704140701e-17j)"
def test_harmonic():
mp.dps = 15
assert harmonic(0) == 0
assert harmonic(1) == 1
assert harmonic(2) == 1.5
assert harmonic(3).ae(1. + 1./2 + 1./3)
assert harmonic(10**10).ae(23.603066594891989701)
assert harmonic(10**1000).ae(2303.162308658947)
assert harmonic(0.5).ae(2-2*log(2))
assert harmonic(inf) == inf
assert harmonic(2+0j) == 1.5+0j
assert harmonic(1+2j).ae(1.4918071802755104+0.92080728264223022j)
def test_gamma_huge_1():
mp.dps = 500
x = mpf(10**10) / 7
mp.dps = 15
assert str(gamma(x)) == "6.26075321389519e+12458010678"
mp.dps = 50
assert str(gamma(x)) == "6.2607532138951929201303779291707455874010420783933e+12458010678"
mp.dps = 15
def test_gamma_huge_2():
mp.dps = 500
x = mpf(10**100) / 19
mp.dps = 15
assert str(gamma(x)) == (\
"1.82341134776679e+5172997469323364168990133558175077136829182824042201886051511"
"9656908623426021308685461258226190190661")
mp.dps = 50
assert str(gamma(x)) == (\
"1.82341134776678875374414910350027596939980412984e+5172997469323364168990133558"
"1750771368291828240422018860515119656908623426021308685461258226190190661")
def test_gamma_huge_3():
mp.dps = 500
x = 10**80 // 3 + 10**70*j / 7
mp.dps = 15
y = gamma(x)
assert str(y.real) == (\
"-6.82925203918106e+2636286142112569524501781477865238132302397236429627932441916"
"056964386399485392600")
assert str(y.imag) == (\
"8.54647143678418e+26362861421125695245017814778652381323023972364296279324419160"
"56964386399485392600")
mp.dps = 50
y = gamma(x)
assert str(y.real) == (\
"-6.8292520391810548460682736226799637356016538421817e+26362861421125695245017814"
"77865238132302397236429627932441916056964386399485392600")
assert str(y.imag) == (\
"8.5464714367841748507479306948130687511711420234015e+263628614211256952450178147"
"7865238132302397236429627932441916056964386399485392600")
def test_gamma_huge_4():
x = 3200+11500j
mp.dps = 15
assert str(gamma(x)) == \
"(8.95783268539713e+5164 - 1.94678798329735e+5164j)"
mp.dps = 50
assert str(gamma(x)) == (\
"(8.9578326853971339570292952697675570822206567327092e+5164"
" - 1.9467879832973509568895402139429643650329524144794e+51"
"64j)")
mp.dps = 15
def test_gamma_huge_5():
mp.dps = 500
x = 10**60 * j / 3
mp.dps = 15
y = gamma(x)
assert str(y.real) == "-3.27753899634941e-227396058973640224580963937571892628368354580620654233316839"
assert str(y.imag) == "-7.1519888950416e-227396058973640224580963937571892628368354580620654233316841"
mp.dps = 50
y = gamma(x)
assert str(y.real) == (\
"-3.2775389963494132168950056995974690946983219123935e-22739605897364022458096393"
"7571892628368354580620654233316839")
assert str(y.imag) == (\
"-7.1519888950415979749736749222530209713136588885897e-22739605897364022458096393"
"7571892628368354580620654233316841")
mp.dps = 15
def test_gamma_huge_7():
mp.dps = 100
a = 3 + j/mpf(10)**1000
mp.dps = 15
y = gamma(a)
assert str(y.real) == "2.0"
# wrong
#assert str(y.imag) == "2.16735365342606e-1000"
assert str(y.imag) == "1.84556867019693e-1000"
mp.dps = 50
y = gamma(a)
assert str(y.real) == "2.0"
#assert str(y.imag) == "2.1673536534260596065418805612488708028522563689298e-1000"
assert str(y.imag) == "1.8455686701969342787869758198351951379156813281202e-1000"
def test_stieltjes():
mp.dps = 15
assert stieltjes(0).ae(+euler)
mp.dps = 25
assert stieltjes(1).ae('-0.07281584548367672486058637587')
assert stieltjes(2).ae('-0.009690363192872318484530386035')
assert stieltjes(3).ae('0.002053834420303345866160046543')
assert stieltjes(4).ae('0.002325370065467300057468170178')
mp.dps = 15
assert stieltjes(1).ae(-0.07281584548367672486058637587)
assert stieltjes(2).ae(-0.009690363192872318484530386035)
assert stieltjes(3).ae(0.002053834420303345866160046543)
assert stieltjes(4).ae(0.0023253700654673000574681701775)
def test_barnesg():
mp.dps = 15
assert barnesg(0) == barnesg(-1) == 0
assert [superfac(i) for i in range(8)] == [1, 1, 2, 12, 288, 34560, 24883200, 125411328000]
assert str(superfac(1000)) == '3.24570818422368e+1177245'
assert isnan(barnesg(nan))
assert isnan(superfac(nan))
assert isnan(hyperfac(nan))
assert barnesg(inf) == inf
assert superfac(inf) == inf
assert hyperfac(inf) == inf
assert isnan(superfac(-inf))
assert barnesg(0.7).ae(0.8068722730141471)
assert barnesg(2+3j).ae(-0.17810213864082169+0.04504542715447838j)
assert [hyperfac(n) for n in range(7)] == [1, 1, 4, 108, 27648, 86400000, 4031078400000]
assert [hyperfac(n) for n in range(0,-7,-1)] == [1,1,-1,-4,108,27648,-86400000]
a = barnesg(-3+0j)
assert a == 0 and isinstance(a, mpc)
a = hyperfac(-3+0j)
assert a == -4 and isinstance(a, mpc)
def test_polylog():
mp.dps = 15
zs = [mpmathify(z) for z in [0, 0.5, 0.99, 4, -0.5, -4, 1j, 3+4j]]
for z in zs: assert polylog(1, z).ae(-log(1-z))
for z in zs: assert polylog(0, z).ae(z/(1-z))
for z in zs: assert polylog(-1, z).ae(z/(1-z)**2)
for z in zs: assert polylog(-2, z).ae(z*(1+z)/(1-z)**3)
for z in zs: assert polylog(-3, z).ae(z*(1+4*z+z**2)/(1-z)**4)
assert polylog(3, 7).ae(5.3192579921456754382-5.9479244480803301023j)
assert polylog(3, -7).ae(-4.5693548977219423182)
assert polylog(2, 0.9).ae(1.2997147230049587252)
assert polylog(2, -0.9).ae(-0.75216317921726162037)
assert polylog(2, 0.9j).ae(-0.17177943786580149299+0.83598828572550503226j)
assert polylog(2, 1.1).ae(1.9619991013055685931-0.2994257606855892575j)
assert polylog(2, -1.1).ae(-0.89083809026228260587)
assert polylog(2, 1.1*sqrt(j)).ae(0.58841571107611387722+1.09962542118827026011j)
assert polylog(-2, 0.9).ae(1710)
assert polylog(-2, -0.9).ae(-90/6859.)
assert polylog(3, 0.9).ae(1.0496589501864398696)
assert polylog(-3, 0.9).ae(48690)
assert polylog(-3, -4).ae(-0.0064)
assert polylog(0.5+j/3, 0.5+j/2).ae(0.31739144796565650535 + 0.99255390416556261437j)
assert polylog(3+4j,1).ae(zeta(3+4j))
assert polylog(3+4j,-1).ae(-altzeta(3+4j))
# issue 390
assert polylog(1.5, -48.910886523731889).ae(-6.272992229311817)
assert polylog(1.5, 200).ae(-8.349608319033686529 - 8.159694826434266042j)
assert polylog(-2+0j, -2).ae(mpf(1)/13.5)
assert polylog(-2+0j, 1.25).ae(-180)
def test_bell_polyexp():
mp.dps = 15
# TODO: more tests for polyexp
assert (polyexp(0,1e-10)*10**10).ae(1.00000000005)
assert (polyexp(1,1e-10)*10**10).ae(1.0000000001)
assert polyexp(5,3j).ae(-607.7044517476176454+519.962786482001476087j)
assert polyexp(-1,3.5).ae(12.09537536175543444)
# bell(0,x) = 1
assert bell(0,0) == 1
assert bell(0,1) == 1
assert bell(0,2) == 1
assert bell(0,inf) == 1
assert bell(0,-inf) == 1
assert isnan(bell(0,nan))
# bell(1,x) = x
assert bell(1,4) == 4
assert bell(1,0) == 0
assert bell(1,inf) == inf
assert bell(1,-inf) == -inf
assert isnan(bell(1,nan))
# bell(2,x) = x*(1+x)
assert bell(2,-1) == 0
assert bell(2,0) == 0
# large orders / arguments
assert bell(10) == 115975
assert bell(10,1) == 115975
assert bell(10, -8) == 11054008
assert bell(5,-50) == -253087550
assert bell(50,-50).ae('3.4746902914629720259e74')
mp.dps = 80
assert bell(50,-50) == 347469029146297202586097646631767227177164818163463279814268368579055777450
assert bell(40,50) == 5575520134721105844739265207408344706846955281965031698187656176321717550
assert bell(74) == 5006908024247925379707076470957722220463116781409659160159536981161298714301202
mp.dps = 15
assert bell(10,20j) == 7504528595600+15649605360020j
# continuity of the generalization
assert bell(0.5,0).ae(sinc(pi*0.5))
def test_primezeta():
mp.dps = 15
assert primezeta(0.9).ae(1.8388316154446882243 + 3.1415926535897932385j)
assert primezeta(4).ae(0.076993139764246844943)
assert primezeta(1) == inf
assert primezeta(inf) == 0
assert isnan(primezeta(nan))
def test_rs_zeta():
mp.dps = 15
assert zeta(0.5+100000j).ae(1.0730320148577531321 + 5.7808485443635039843j)
assert zeta(0.75+100000j).ae(1.837852337251873704 + 1.9988492668661145358j)
assert zeta(0.5+1000000j, derivative=3).ae(1647.7744105852674733 - 1423.1270943036622097j)
assert zeta(1+1000000j, derivative=3).ae(3.4085866124523582894 - 18.179184721525947301j)
assert zeta(1+1000000j, derivative=1).ae(-0.10423479366985452134 - 0.74728992803359056244j)
assert zeta(0.5-1000000j, derivative=1).ae(11.636804066002521459 + 17.127254072212996004j)
# Additional sanity tests using fp arithmetic.
# Some more high-precision tests are found in the docstrings
def ae(x, y, tol=1e-6):
return abs(x-y) < tol*abs(y)
assert ae(fp.zeta(0.5-100000j), 1.0730320148577531321 - 5.7808485443635039843j)
assert ae(fp.zeta(0.75-100000j), 1.837852337251873704 - 1.9988492668661145358j)
assert ae(fp.zeta(0.5+1e6j), 0.076089069738227100006 + 2.8051021010192989554j)
assert ae(fp.zeta(0.5+1e6j, derivative=1), 11.636804066002521459 - 17.127254072212996004j)
assert ae(fp.zeta(1+1e6j), 0.94738726251047891048 + 0.59421999312091832833j)
assert ae(fp.zeta(1+1e6j, derivative=1), -0.10423479366985452134 - 0.74728992803359056244j)
assert ae(fp.zeta(0.5+100000j, derivative=1), 10.766962036817482375 - 30.92705282105996714j)
assert ae(fp.zeta(0.5+100000j, derivative=2), -119.40515625740538429 + 217.14780631141830251j)
assert ae(fp.zeta(0.5+100000j, derivative=3), 1129.7550282628460881 - 1685.4736895169690346j)
assert ae(fp.zeta(0.5+100000j, derivative=4), -10407.160819314958615 + 13777.786698628045085j)
assert ae(fp.zeta(0.75+100000j, derivative=1), -0.41742276699594321475 - 6.4453816275049955949j)
assert ae(fp.zeta(0.75+100000j, derivative=2), -9.214314279161977266 + 35.07290795337967899j)
assert ae(fp.zeta(0.75+100000j, derivative=3), 110.61331857820103469 - 236.87847130518129926j)
assert ae(fp.zeta(0.75+100000j, derivative=4), -1054.334275898559401 + 1769.9177890161596383j)
def test_siegelz():
mp.dps = 15
assert siegelz(100000).ae(5.87959246868176504171)
assert siegelz(100000, derivative=2).ae(-54.1172711010126452832)
assert siegelz(100000, derivative=3).ae(-278.930831343966552538)
assert siegelz(100000+j,derivative=1).ae(678.214511857070283307-379.742160779916375413j)
def test_zeta_near_1():
# Test for a former bug in mpf_zeta and mpc_zeta
mp.dps = 15
s1 = fadd(1, '1e-10', exact=True)
s2 = fadd(1, '-1e-10', exact=True)
s3 = fadd(1, '1e-10j', exact=True)
assert zeta(s1).ae(1.000000000057721566490881444e10)
assert zeta(s2).ae(-9.99999999942278433510574872e9)
z = zeta(s3)
assert z.real.ae(0.57721566490153286060)
assert z.imag.ae(-9.9999999999999999999927184e9)
mp.dps = 30
s1 = fadd(1, '1e-50', exact=True)
s2 = fadd(1, '-1e-50', exact=True)
s3 = fadd(1, '1e-50j', exact=True)
assert zeta(s1).ae('1e50')
assert zeta(s2).ae('-1e50')
z = zeta(s3)
assert z.real.ae('0.57721566490153286060651209008240243104215933593992')
assert z.imag.ae('-1e50')

View File

@ -0,0 +1,291 @@
"""
Check that the output from irrational functions is accurate for
high-precision input, from 5 to 200 digits. The reference values were
verified with Mathematica.
"""
import time
from mpmath import *
precs = [5, 15, 28, 35, 57, 80, 100, 150, 200]
# sqrt(3) + pi/2
a = \
"3.302847134363773912758768033145623809041389953497933538543279275605"\
"841220051904536395163599428307109666700184672047856353516867399774243594"\
"67433521615861420725323528325327484262075464241255915238845599752675"
# e + 1/euler**2
b = \
"5.719681166601007617111261398629939965860873957353320734275716220045750"\
"31474116300529519620938123730851145473473708966080207482581266469342214"\
"824842256999042984813905047895479210702109260221361437411947323431"
# sqrt(a)
sqrt_a = \
"1.817373691447021556327498239690365674922395036495564333152483422755"\
"144321726165582817927383239308173567921345318453306994746434073691275094"\
"484777905906961689902608644112196725896908619756404253109722911487"
# sqrt(a+b*i).real
sqrt_abi_real = \
"2.225720098415113027729407777066107959851146508557282707197601407276"\
"89160998185797504198062911768240808839104987021515555650875977724230130"\
"3584116233925658621288393930286871862273400475179312570274423840384"
# sqrt(a+b*i).imag
sqrt_abi_imag = \
"1.2849057639084690902371581529110949983261182430040898147672052833653668"\
"0629534491275114877090834296831373498336559849050755848611854282001250"\
"1924311019152914021365263161630765255610885489295778894976075186"
# log(a)
log_a = \
"1.194784864491089550288313512105715261520511949410072046160598707069"\
"4336653155025770546309137440687056366757650909754708302115204338077595203"\
"83005773986664564927027147084436553262269459110211221152925732612"
# log(a+b*i).real
log_abi_real = \
"1.8877985921697018111624077550443297276844736840853590212962006811663"\
"04949387789489704203167470111267581371396245317618589339274243008242708"\
"014251531496104028712866224020066439049377679709216784954509456421"
# log(a+b*i).imag
log_abi_imag = \
"1.0471204952840802663567714297078763189256357109769672185219334169734948"\
"4265809854092437285294686651806426649541504240470168212723133326542181"\
"8300136462287639956713914482701017346851009323172531601894918640"
# exp(a)
exp_a = \
"27.18994224087168661137253262213293847994194869430518354305430976149"\
"382792035050358791398632888885200049857986258414049540376323785711941636"\
"100358982497583832083513086941635049329804685212200507288797531143"
# exp(a+b*i).real
exp_abi_real = \
"22.98606617170543596386921087657586890620262522816912505151109385026"\
"40160179326569526152851983847133513990281518417211964710397233157168852"\
"4963130831190142571659948419307628119985383887599493378056639916701"
# exp(a+b*i).imag
exp_abi_imag = \
"-14.523557450291489727214750571590272774669907424478129280902375851196283"\
"3377162379031724734050088565710975758824441845278120105728824497308303"\
"6065619788140201636218705414429933685889542661364184694108251449"
# a**b
pow_a_b = \
"928.7025342285568142947391505837660251004990092821305668257284426997"\
"361966028275685583421197860603126498884545336686124793155581311527995550"\
"580229264427202446131740932666832138634013168125809402143796691154"
# (a**(a+b*i)).real
pow_a_abi_real = \
"44.09156071394489511956058111704382592976814280267142206420038656267"\
"67707916510652790502399193109819563864568986234654864462095231138500505"\
"8197456514795059492120303477512711977915544927440682508821426093455"
# (a**(a+b*i)).imag
pow_a_abi_imag = \
"27.069371511573224750478105146737852141664955461266218367212527612279886"\
"9322304536553254659049205414427707675802193810711302947536332040474573"\
"8166261217563960235014674118610092944307893857862518964990092301"
# ((a+b*i)**(a+b*i)).real
pow_abi_abi_real = \
"-0.15171310677859590091001057734676423076527145052787388589334350524"\
"8084195882019497779202452975350579073716811284169068082670778986235179"\
"0813026562962084477640470612184016755250592698408112493759742219150452"\
# ((a+b*i)**(a+b*i)).imag
pow_abi_abi_imag = \
"1.2697592504953448936553147870155987153192995316950583150964099070426"\
"4736837932577176947632535475040521749162383347758827307504526525647759"\
"97547638617201824468382194146854367480471892602963428122896045019902"
# sin(a)
sin_a = \
"-0.16055653857469062740274792907968048154164433772938156243509084009"\
"38437090841460493108570147191289893388608611542655654723437248152535114"\
"528368009465836614227575701220612124204622383149391870684288862269631"
# sin(1000*a)
sin_1000a = \
"-0.85897040577443833776358106803777589664322997794126153477060795801"\
"09151695416961724733492511852267067419573754315098042850381158563024337"\
"216458577140500488715469780315833217177634490142748614625281171216863"
# sin(a+b*i)
sin_abi_real = \
"-24.4696999681556977743346798696005278716053366404081910969773939630"\
"7149215135459794473448465734589287491880563183624997435193637389884206"\
"02151395451271809790360963144464736839412254746645151672423256977064"
sin_abi_imag = \
"-150.42505378241784671801405965872972765595073690984080160750785565810981"\
"8314482499135443827055399655645954830931316357243750839088113122816583"\
"7169201254329464271121058839499197583056427233866320456505060735"
# cos
cos_a = \
"-0.98702664499035378399332439243967038895709261414476495730788864004"\
"05406821549361039745258003422386169330787395654908532996287293003581554"\
"257037193284199198069707141161341820684198547572456183525659969145501"
cos_1000a = \
"-0.51202523570982001856195696460663971099692261342827540426136215533"\
"52686662667660613179619804463250686852463876088694806607652218586060613"\
"951310588158830695735537073667299449753951774916401887657320950496820"
# tan
tan_a = \
"0.162666873675188117341401059858835168007137819495998960250142156848"\
"639654718809412181543343168174807985559916643549174530459883826451064966"\
"7996119428949951351938178809444268785629011625179962457123195557310"
tan_abi_real = \
"6.822696615947538488826586186310162599974827139564433912601918442911"\
"1026830824380070400102213741875804368044342309515353631134074491271890"\
"467615882710035471686578162073677173148647065131872116479947620E-6"
tan_abi_imag = \
"0.9999795833048243692245661011298447587046967777739649018690797625964167"\
"1446419978852235960862841608081413169601038230073129482874832053357571"\
"62702259309150715669026865777947502665936317953101462202542168429"
def test_hp():
for dps in precs:
mp.dps = dps + 8
aa = mpf(a)
bb = mpf(b)
a1000 = 1000*mpf(a)
abi = mpc(aa, bb)
mp.dps = dps
assert (sqrt(3) + pi/2).ae(aa)
assert (e + 1/euler**2).ae(bb)
assert sqrt(aa).ae(mpf(sqrt_a))
assert sqrt(abi).ae(mpc(sqrt_abi_real, sqrt_abi_imag))
assert log(aa).ae(mpf(log_a))
assert log(abi).ae(mpc(log_abi_real, log_abi_imag))
assert exp(aa).ae(mpf(exp_a))
assert exp(abi).ae(mpc(exp_abi_real, exp_abi_imag))
assert (aa**bb).ae(mpf(pow_a_b))
assert (aa**abi).ae(mpc(pow_a_abi_real, pow_a_abi_imag))
assert (abi**abi).ae(mpc(pow_abi_abi_real, pow_abi_abi_imag))
assert sin(a).ae(mpf(sin_a))
assert sin(a1000).ae(mpf(sin_1000a))
assert sin(abi).ae(mpc(sin_abi_real, sin_abi_imag))
assert cos(a).ae(mpf(cos_a))
assert cos(a1000).ae(mpf(cos_1000a))
assert tan(a).ae(mpf(tan_a))
assert tan(abi).ae(mpc(tan_abi_real, tan_abi_imag))
# check that complex cancellation is avoided so that both
# real and imaginary parts have high relative accuracy.
# abs_eps should be 0, but has to be set to 1e-205 to pass the
# 200-digit case, probably due to slight inaccuracy in the
# precomputed input
assert (tan(abi).real).ae(mpf(tan_abi_real), abs_eps=1e-205)
assert (tan(abi).imag).ae(mpf(tan_abi_imag), abs_eps=1e-205)
mp.dps = 460
assert str(log(3))[-20:] == '02166121184001409826'
mp.dps = 15
# Since str(a) can differ in the last digit from rounded a, and I want
# to compare the last digits of big numbers with the results in Mathematica,
# I made this hack to get the last 20 digits of rounded a
def last_digits(a):
r = repr(a)
s = str(a)
#dps = mp.dps
#mp.dps += 3
m = 10
r = r.replace(s[:-m],'')
r = r.replace("mpf('",'').replace("')",'')
num0 = 0
for c in r:
if c == '0':
num0 += 1
else:
break
b = float(int(r))/10**(len(r) - m)
if b >= 10**m - 0.5: # pragma: no cover
raise NotImplementedError
n = int(round(b))
sn = str(n)
s = s[:-m] + '0'*num0 + sn
return s[-20:]
# values checked with Mathematica
def test_log_hp():
mp.dps = 2000
a = mpf(10)**15000/3
r = log(a)
res = last_digits(r)
# Mathematica N[Log[10^15000/3], 2000]
# ...7443804441768333470331
assert res == '43804441768333470331'
# see issue 145
r = log(mpf(3)/2)
# Mathematica N[Log[3/2], 2000]
# ...69653749808140753263288
res = last_digits(r)
assert res == '53749808140753263288'
mp.dps = 10000
r = log(2)
res = last_digits(r)
# Mathematica N[Log[2], 10000]
# ...695615913401856601359655561
assert res == '13401856601359655561'
r = log(mpf(10)**10/3)
res = last_digits(r)
# Mathematica N[Log[10^10/3], 10000]
# ...587087654020631943060007154
assert res == '54020631943060007154', res
r = log(mpf(10)**100/3)
res = last_digits(r)
# Mathematica N[Log[10^100/3], 10000]
# ,,,59246336539088351652334666
assert res == '36539088351652334666', res
mp.dps += 10
a = 1 - mpf(1)/10**10
mp.dps -= 10
r = log(a)
res = last_digits(r)
# ...3310334360482956137216724048322957404
# 372167240483229574038733026370
# Mathematica N[Log[1 - 10^-10]*10^10, 10000]
# ...60482956137216724048322957404
assert res == '37216724048322957404', res
mp.dps = 10000
mp.dps += 100
a = 1 + mpf(1)/10**100
mp.dps -= 100
r = log(a)
res = last_digits(+r)
# Mathematica N[Log[1 + 10^-100]*10^10, 10030]
# ...3994733877377412241546890854692521568292338268273 10^-91
assert res == '39947338773774122415', res
mp.dps = 15
def test_exp_hp():
mp.dps = 4000
r = exp(mpf(1)/10)
# IntegerPart[N[Exp[1/10] * 10^4000, 4000]]
# ...92167105162069688129
assert int(r * 10**mp.dps) % 10**20 == 92167105162069688129

View File

@ -0,0 +1,19 @@
from mpmath import *
def test_pslq():
mp.dps = 15
assert pslq([3*pi+4*e/7, pi, e, log(2)]) == [7, -21, -4, 0]
assert pslq([4.9999999999999991, 1]) == [1, -5]
assert pslq([2,1]) == [1, -2]
def test_identify():
mp.dps = 20
assert identify(zeta(4), ['log(2)', 'pi**4']) == '((1/90)*pi**4)'
mp.dps = 15
assert identify(exp(5)) == 'exp(5)'
assert identify(exp(4)) == 'exp(4)'
assert identify(log(5)) == 'log(5)'
assert identify(exp(3*pi), ['pi']) == 'exp((3*pi))'
assert identify(3, full=True) == ['3', '3', '1/(1/3)', 'sqrt(9)',
'1/sqrt((1/9))', '(sqrt(12)/2)**2', '1/(sqrt(12)/6)**2']
assert identify(pi+1, {'a':+pi}) == '(1 + 1*a)'

View File

@ -0,0 +1,453 @@
from mpmath import *
def test_interval_identity():
iv.dps = 15
assert mpi(2) == mpi(2, 2)
assert mpi(2) != mpi(-2, 2)
assert not (mpi(2) != mpi(2, 2))
assert mpi(-1, 1) == mpi(-1, 1)
assert str(mpi('0.1')) == "[0.099999999999999991673, 0.10000000000000000555]"
assert repr(mpi('0.1')) == "mpi('0.099999999999999992', '0.10000000000000001')"
u = mpi(-1, 3)
assert -1 in u
assert 2 in u
assert 3 in u
assert -1.1 not in u
assert 3.1 not in u
assert mpi(-1, 3) in u
assert mpi(0, 1) in u
assert mpi(-1.1, 2) not in u
assert mpi(2.5, 3.1) not in u
w = mpi(-inf, inf)
assert mpi(-5, 5) in w
assert mpi(2, inf) in w
assert mpi(0, 2) in mpi(0, 10)
assert not (3 in mpi(-inf, 0))
def test_interval_hash():
assert hash(mpi(3)) == hash(3)
assert hash(mpi(3.25)) == hash(3.25)
assert hash(mpi(3,4)) == hash(mpi(3,4))
assert hash(iv.mpc(3)) == hash(3)
assert hash(iv.mpc(3,4)) == hash(3+4j)
assert hash(iv.mpc((1,3),(2,4))) == hash(iv.mpc((1,3),(2,4)))
def test_interval_arithmetic():
iv.dps = 15
assert mpi(2) + mpi(3,4) == mpi(5,6)
assert mpi(1, 2)**2 == mpi(1, 4)
assert mpi(1) + mpi(0, 1e-50) == mpi(1, mpf('1.0000000000000002'))
x = 1 / (1 / mpi(3))
assert x.a < 3 < x.b
x = mpi(2) ** mpi(0.5)
iv.dps += 5
sq = iv.sqrt(2)
iv.dps -= 5
assert x.a < sq < x.b
assert mpi(1) / mpi(1, inf)
assert mpi(2, 3) / inf == mpi(0, 0)
assert mpi(0) / inf == 0
assert mpi(0) / 0 == mpi(-inf, inf)
assert mpi(inf) / 0 == mpi(-inf, inf)
assert mpi(0) * inf == mpi(-inf, inf)
assert 1 / mpi(2, inf) == mpi(0, 0.5)
assert str((mpi(50, 50) * mpi(-10, -10)) / 3) == \
'[-166.66666666666668561, -166.66666666666665719]'
assert mpi(0, 4) ** 3 == mpi(0, 64)
assert mpi(2,4).mid == 3
iv.dps = 30
a = mpi(iv.pi)
iv.dps = 15
b = +a
assert b.a < a.a
assert b.b > a.b
a = mpi(iv.pi)
assert a == +a
assert abs(mpi(-1,2)) == mpi(0,2)
assert abs(mpi(0.5,2)) == mpi(0.5,2)
assert abs(mpi(-3,2)) == mpi(0,3)
assert abs(mpi(-3,-0.5)) == mpi(0.5,3)
assert mpi(0) * mpi(2,3) == mpi(0)
assert mpi(2,3) * mpi(0) == mpi(0)
assert mpi(1,3).delta == 2
assert mpi(1,2) - mpi(3,4) == mpi(-3,-1)
assert mpi(-inf,0) - mpi(0,inf) == mpi(-inf,0)
assert mpi(-inf,0) - mpi(-inf,inf) == mpi(-inf,inf)
assert mpi(0,inf) - mpi(-inf,1) == mpi(-1,inf)
def test_interval_mul():
assert mpi(-1, 0) * inf == mpi(-inf, 0)
assert mpi(-1, 0) * -inf == mpi(0, inf)
assert mpi(0, 1) * inf == mpi(0, inf)
assert mpi(0, 1) * mpi(0, inf) == mpi(0, inf)
assert mpi(-1, 1) * inf == mpi(-inf, inf)
assert mpi(-1, 1) * mpi(0, inf) == mpi(-inf, inf)
assert mpi(-1, 1) * mpi(-inf, inf) == mpi(-inf, inf)
assert mpi(-inf, 0) * mpi(0, 1) == mpi(-inf, 0)
assert mpi(-inf, 0) * mpi(0, 0) * mpi(-inf, 0)
assert mpi(-inf, 0) * mpi(-inf, inf) == mpi(-inf, inf)
assert mpi(-5,0)*mpi(-32,28) == mpi(-140,160)
assert mpi(2,3) * mpi(-1,2) == mpi(-3,6)
# Should be undefined?
assert mpi(inf, inf) * 0 == mpi(-inf, inf)
assert mpi(-inf, -inf) * 0 == mpi(-inf, inf)
assert mpi(0) * mpi(-inf,2) == mpi(-inf,inf)
assert mpi(0) * mpi(-2,inf) == mpi(-inf,inf)
assert mpi(-2,inf) * mpi(0) == mpi(-inf,inf)
assert mpi(-inf,2) * mpi(0) == mpi(-inf,inf)
def test_interval_pow():
assert mpi(3)**2 == mpi(9, 9)
assert mpi(-3)**2 == mpi(9, 9)
assert mpi(-3, 1)**2 == mpi(0, 9)
assert mpi(-3, -1)**2 == mpi(1, 9)
assert mpi(-3, -1)**3 == mpi(-27, -1)
assert mpi(-3, 1)**3 == mpi(-27, 1)
assert mpi(-2, 3)**2 == mpi(0, 9)
assert mpi(-3, 2)**2 == mpi(0, 9)
assert mpi(4) ** -1 == mpi(0.25, 0.25)
assert mpi(-4) ** -1 == mpi(-0.25, -0.25)
assert mpi(4) ** -2 == mpi(0.0625, 0.0625)
assert mpi(-4) ** -2 == mpi(0.0625, 0.0625)
assert mpi(0, 1) ** inf == mpi(0, 1)
assert mpi(0, 1) ** -inf == mpi(1, inf)
assert mpi(0, inf) ** inf == mpi(0, inf)
assert mpi(0, inf) ** -inf == mpi(0, inf)
assert mpi(1, inf) ** inf == mpi(1, inf)
assert mpi(1, inf) ** -inf == mpi(0, 1)
assert mpi(2, 3) ** 1 == mpi(2, 3)
assert mpi(2, 3) ** 0 == 1
assert mpi(1,3) ** mpi(2) == mpi(1,9)
def test_interval_sqrt():
assert mpi(4) ** 0.5 == mpi(2)
def test_interval_div():
assert mpi(0.5, 1) / mpi(-1, 0) == mpi(-inf, -0.5)
assert mpi(0, 1) / mpi(0, 1) == mpi(0, inf)
assert mpi(inf, inf) / mpi(inf, inf) == mpi(0, inf)
assert mpi(inf, inf) / mpi(2, inf) == mpi(0, inf)
assert mpi(inf, inf) / mpi(2, 2) == mpi(inf, inf)
assert mpi(0, inf) / mpi(2, inf) == mpi(0, inf)
assert mpi(0, inf) / mpi(2, 2) == mpi(0, inf)
assert mpi(2, inf) / mpi(2, 2) == mpi(1, inf)
assert mpi(2, inf) / mpi(2, inf) == mpi(0, inf)
assert mpi(-4, 8) / mpi(1, inf) == mpi(-4, 8)
assert mpi(-4, 8) / mpi(0.5, inf) == mpi(-8, 16)
assert mpi(-inf, 8) / mpi(0.5, inf) == mpi(-inf, 16)
assert mpi(-inf, inf) / mpi(0.5, inf) == mpi(-inf, inf)
assert mpi(8, inf) / mpi(0.5, inf) == mpi(0, inf)
assert mpi(-8, inf) / mpi(0.5, inf) == mpi(-16, inf)
assert mpi(-4, 8) / mpi(inf, inf) == mpi(0, 0)
assert mpi(0, 8) / mpi(inf, inf) == mpi(0, 0)
assert mpi(0, 0) / mpi(inf, inf) == mpi(0, 0)
assert mpi(-inf, 0) / mpi(inf, inf) == mpi(-inf, 0)
assert mpi(-inf, 8) / mpi(inf, inf) == mpi(-inf, 0)
assert mpi(-inf, inf) / mpi(inf, inf) == mpi(-inf, inf)
assert mpi(-8, inf) / mpi(inf, inf) == mpi(0, inf)
assert mpi(0, inf) / mpi(inf, inf) == mpi(0, inf)
assert mpi(8, inf) / mpi(inf, inf) == mpi(0, inf)
assert mpi(inf, inf) / mpi(inf, inf) == mpi(0, inf)
assert mpi(-1, 2) / mpi(0, 1) == mpi(-inf, +inf)
assert mpi(0, 1) / mpi(0, 1) == mpi(0.0, +inf)
assert mpi(-1, 0) / mpi(0, 1) == mpi(-inf, 0.0)
assert mpi(-0.5, -0.25) / mpi(0, 1) == mpi(-inf, -0.25)
assert mpi(0.5, 1) / mpi(0, 1) == mpi(0.5, +inf)
assert mpi(0.5, 4) / mpi(0, 1) == mpi(0.5, +inf)
assert mpi(-1, -0.5) / mpi(0, 1) == mpi(-inf, -0.5)
assert mpi(-4, -0.5) / mpi(0, 1) == mpi(-inf, -0.5)
assert mpi(-1, 2) / mpi(-2, 0.5) == mpi(-inf, +inf)
assert mpi(0, 1) / mpi(-2, 0.5) == mpi(-inf, +inf)
assert mpi(-1, 0) / mpi(-2, 0.5) == mpi(-inf, +inf)
assert mpi(-0.5, -0.25) / mpi(-2, 0.5) == mpi(-inf, +inf)
assert mpi(0.5, 1) / mpi(-2, 0.5) == mpi(-inf, +inf)
assert mpi(0.5, 4) / mpi(-2, 0.5) == mpi(-inf, +inf)
assert mpi(-1, -0.5) / mpi(-2, 0.5) == mpi(-inf, +inf)
assert mpi(-4, -0.5) / mpi(-2, 0.5) == mpi(-inf, +inf)
assert mpi(-1, 2) / mpi(-1, 0) == mpi(-inf, +inf)
assert mpi(0, 1) / mpi(-1, 0) == mpi(-inf, 0.0)
assert mpi(-1, 0) / mpi(-1, 0) == mpi(0.0, +inf)
assert mpi(-0.5, -0.25) / mpi(-1, 0) == mpi(0.25, +inf)
assert mpi(0.5, 1) / mpi(-1, 0) == mpi(-inf, -0.5)
assert mpi(0.5, 4) / mpi(-1, 0) == mpi(-inf, -0.5)
assert mpi(-1, -0.5) / mpi(-1, 0) == mpi(0.5, +inf)
assert mpi(-4, -0.5) / mpi(-1, 0) == mpi(0.5, +inf)
assert mpi(-1, 2) / mpi(0.5, 1) == mpi(-2.0, 4.0)
assert mpi(0, 1) / mpi(0.5, 1) == mpi(0.0, 2.0)
assert mpi(-1, 0) / mpi(0.5, 1) == mpi(-2.0, 0.0)
assert mpi(-0.5, -0.25) / mpi(0.5, 1) == mpi(-1.0, -0.25)
assert mpi(0.5, 1) / mpi(0.5, 1) == mpi(0.5, 2.0)
assert mpi(0.5, 4) / mpi(0.5, 1) == mpi(0.5, 8.0)
assert mpi(-1, -0.5) / mpi(0.5, 1) == mpi(-2.0, -0.5)
assert mpi(-4, -0.5) / mpi(0.5, 1) == mpi(-8.0, -0.5)
assert mpi(-1, 2) / mpi(-2, -0.5) == mpi(-4.0, 2.0)
assert mpi(0, 1) / mpi(-2, -0.5) == mpi(-2.0, 0.0)
assert mpi(-1, 0) / mpi(-2, -0.5) == mpi(0.0, 2.0)
assert mpi(-0.5, -0.25) / mpi(-2, -0.5) == mpi(0.125, 1.0)
assert mpi(0.5, 1) / mpi(-2, -0.5) == mpi(-2.0, -0.25)
assert mpi(0.5, 4) / mpi(-2, -0.5) == mpi(-8.0, -0.25)
assert mpi(-1, -0.5) / mpi(-2, -0.5) == mpi(0.25, 2.0)
assert mpi(-4, -0.5) / mpi(-2, -0.5) == mpi(0.25, 8.0)
# Should be undefined?
assert mpi(0, 0) / mpi(0, 0) == mpi(-inf, inf)
assert mpi(0, 0) / mpi(0, 1) == mpi(-inf, inf)
def test_interval_cos_sin():
iv.dps = 15
cos = iv.cos
sin = iv.sin
tan = iv.tan
pi = iv.pi
# Around 0
assert cos(mpi(0)) == 1
assert sin(mpi(0)) == 0
assert cos(mpi(0,1)) == mpi(0.54030230586813965399, 1.0)
assert sin(mpi(0,1)) == mpi(0, 0.8414709848078966159)
assert cos(mpi(1,2)) == mpi(-0.4161468365471424069, 0.54030230586813976501)
assert sin(mpi(1,2)) == mpi(0.84147098480789650488, 1.0)
assert sin(mpi(1,2.5)) == mpi(0.59847214410395643824, 1.0)
assert cos(mpi(-1, 1)) == mpi(0.54030230586813965399, 1.0)
assert cos(mpi(-1, 0.5)) == mpi(0.54030230586813965399, 1.0)
assert cos(mpi(-1, 1.5)) == mpi(0.070737201667702906405, 1.0)
assert sin(mpi(-1,1)) == mpi(-0.8414709848078966159, 0.8414709848078966159)
assert sin(mpi(-1,0.5)) == mpi(-0.8414709848078966159, 0.47942553860420300538)
assert mpi(-0.8414709848078966159, 1.00000000000000002e-100) in sin(mpi(-1,1e-100))
assert mpi(-2.00000000000000004e-100, 1.00000000000000002e-100) in sin(mpi(-2e-100,1e-100))
# Same interval
assert cos(mpi(2, 2.5))
assert cos(mpi(3.5, 4)) == mpi(-0.93645668729079634129, -0.65364362086361182946)
assert cos(mpi(5, 5.5)) == mpi(0.28366218546322624627, 0.70866977429126010168)
assert mpi(0.59847214410395654927, 0.90929742682568170942) in sin(mpi(2, 2.5))
assert sin(mpi(3.5, 4)) == mpi(-0.75680249530792831347, -0.35078322768961983646)
assert sin(mpi(5, 5.5)) == mpi(-0.95892427466313856499, -0.70554032557039181306)
# Higher roots
iv.dps = 55
w = 4*10**50 + mpi(0.5)
for p in [15, 40, 80]:
iv.dps = p
assert 0 in sin(4*mpi(pi))
assert 0 in sin(4*10**50*mpi(pi))
assert 0 in cos((4+0.5)*mpi(pi))
assert 0 in cos(w*mpi(pi))
assert 1 in cos(4*mpi(pi))
assert 1 in cos(4*10**50*mpi(pi))
iv.dps = 15
assert cos(mpi(2,inf)) == mpi(-1,1)
assert sin(mpi(2,inf)) == mpi(-1,1)
assert cos(mpi(-inf,2)) == mpi(-1,1)
assert sin(mpi(-inf,2)) == mpi(-1,1)
u = tan(mpi(0.5,1))
assert mpf(u.a).ae(mp.tan(0.5))
assert mpf(u.b).ae(mp.tan(1))
v = iv.cot(mpi(0.5,1))
assert mpf(v.a).ae(mp.cot(1))
assert mpf(v.b).ae(mp.cot(0.5))
# Sanity check of evaluation at n*pi and (n+1/2)*pi
for n in range(-5,7,2):
x = iv.cos(n*iv.pi)
assert -1 in x
assert x >= -1
assert x != -1
x = iv.sin((n+0.5)*iv.pi)
assert -1 in x
assert x >= -1
assert x != -1
for n in range(-6,8,2):
x = iv.cos(n*iv.pi)
assert 1 in x
assert x <= 1
if n:
assert x != 1
x = iv.sin((n+0.5)*iv.pi)
assert 1 in x
assert x <= 1
assert x != 1
for n in range(-6,7):
x = iv.cos((n+0.5)*iv.pi)
assert x.a < 0 < x.b
x = iv.sin(n*iv.pi)
if n:
assert x.a < 0 < x.b
def test_interval_complex():
# TODO: many more tests
iv.dps = 15
mp.dps = 15
assert iv.mpc(2,3) == 2+3j
assert iv.mpc(2,3) != 2+4j
assert iv.mpc(2,3) != 1+3j
assert 1+3j in iv.mpc([1,2],[3,4])
assert 2+5j not in iv.mpc([1,2],[3,4])
assert iv.mpc(1,2) + 1j == 1+3j
assert iv.mpc([1,2],[2,3]) + 2+3j == iv.mpc([3,4],[5,6])
assert iv.mpc([2,4],[4,8]) / 2 == iv.mpc([1,2],[2,4])
assert iv.mpc([1,2],[2,4]) * 2j == iv.mpc([-8,-4],[2,4])
assert iv.mpc([2,4],[4,8]) / 2j == iv.mpc([2,4],[-2,-1])
assert iv.exp(2+3j).ae(mp.exp(2+3j))
assert iv.log(2+3j).ae(mp.log(2+3j))
assert (iv.mpc(2,3) ** iv.mpc(0.5,2)).ae(mp.mpc(2,3) ** mp.mpc(0.5,2))
assert 1j in (iv.mpf(-1) ** 0.5)
assert 1j in (iv.mpc(-1) ** 0.5)
assert abs(iv.mpc(0)) == 0
assert abs(iv.mpc(inf)) == inf
assert abs(iv.mpc(3,4)) == 5
assert abs(iv.mpc(4)) == 4
assert abs(iv.mpc(0,4)) == 4
assert abs(iv.mpc(0,[2,3])) == iv.mpf([2,3])
assert abs(iv.mpc(0,[-3,2])) == iv.mpf([0,3])
assert abs(iv.mpc([3,5],[4,12])) == iv.mpf([5,13])
assert abs(iv.mpc([3,5],[-4,12])) == iv.mpf([3,13])
assert iv.mpc(2,3) ** 0 == 1
assert iv.mpc(2,3) ** 1 == (2+3j)
assert iv.mpc(2,3) ** 2 == (2+3j)**2
assert iv.mpc(2,3) ** 3 == (2+3j)**3
assert iv.mpc(2,3) ** 4 == (2+3j)**4
assert iv.mpc(2,3) ** 5 == (2+3j)**5
assert iv.mpc(2,2) ** (-1) == (2+2j) ** (-1)
assert iv.mpc(2,2) ** (-2) == (2+2j) ** (-2)
assert iv.cos(2).ae(mp.cos(2))
assert iv.sin(2).ae(mp.sin(2))
assert iv.cos(2+3j).ae(mp.cos(2+3j))
assert iv.sin(2+3j).ae(mp.sin(2+3j))
def test_interval_complex_arg():
mp.dps = 15
iv.dps = 15
assert iv.arg(3) == 0
assert iv.arg(0) == 0
assert iv.arg([0,3]) == 0
assert iv.arg(-3).ae(pi)
assert iv.arg(2+3j).ae(iv.arg(2+3j))
z = iv.mpc([-2,-1],[3,4])
t = iv.arg(z)
assert t.a.ae(mp.arg(-1+4j))
assert t.b.ae(mp.arg(-2+3j))
z = iv.mpc([-2,1],[3,4])
t = iv.arg(z)
assert t.a.ae(mp.arg(1+3j))
assert t.b.ae(mp.arg(-2+3j))
z = iv.mpc([1,2],[3,4])
t = iv.arg(z)
assert t.a.ae(mp.arg(2+3j))
assert t.b.ae(mp.arg(1+4j))
z = iv.mpc([1,2],[-2,3])
t = iv.arg(z)
assert t.a.ae(mp.arg(1-2j))
assert t.b.ae(mp.arg(1+3j))
z = iv.mpc([1,2],[-4,-3])
t = iv.arg(z)
assert t.a.ae(mp.arg(1-4j))
assert t.b.ae(mp.arg(2-3j))
z = iv.mpc([-1,2],[-4,-3])
t = iv.arg(z)
assert t.a.ae(mp.arg(-1-3j))
assert t.b.ae(mp.arg(2-3j))
z = iv.mpc([-2,-1],[-4,-3])
t = iv.arg(z)
assert t.a.ae(mp.arg(-2-3j))
assert t.b.ae(mp.arg(-1-4j))
z = iv.mpc([-2,-1],[-3,3])
t = iv.arg(z)
assert t.a.ae(-mp.pi)
assert t.b.ae(mp.pi)
z = iv.mpc([-2,2],[-3,3])
t = iv.arg(z)
assert t.a.ae(-mp.pi)
assert t.b.ae(mp.pi)
def test_interval_ae():
iv.dps = 15
x = iv.mpf([1,2])
assert x.ae(1) is None
assert x.ae(1.5) is None
assert x.ae(2) is None
assert x.ae(2.01) is False
assert x.ae(0.99) is False
x = iv.mpf(3.5)
assert x.ae(3.5) is True
assert x.ae(3.5+1e-15) is True
assert x.ae(3.5-1e-15) is True
assert x.ae(3.501) is False
assert x.ae(3.499) is False
assert x.ae(iv.mpf([3.5,3.501])) is None
assert x.ae(iv.mpf([3.5,4.5+1e-15])) is None
def test_interval_nstr():
iv.dps = n = 30
x = mpi(1, 2)
# FIXME: error_dps should not be necessary
assert iv.nstr(x, n, mode='plusminus', error_dps=6) == '1.5 +- 0.5'
assert iv.nstr(x, n, mode='plusminus', use_spaces=False, error_dps=6) == '1.5+-0.5'
assert iv.nstr(x, n, mode='percent') == '1.5 (33.33%)'
assert iv.nstr(x, n, mode='brackets', use_spaces=False) == '[1.0,2.0]'
assert iv.nstr(x, n, mode='brackets' , brackets=('<', '>')) == '<1.0, 2.0>'
x = mpi('5.2582327113062393041', '5.2582327113062749951')
assert iv.nstr(x, n, mode='diff') == '5.2582327113062[393041, 749951]'
assert iv.nstr(iv.cos(mpi(1)), n, mode='diff', use_spaces=False) == '0.54030230586813971740093660744[2955,3053]'
assert iv.nstr(mpi('1e123', '1e129'), n, mode='diff') == '[1.0e+123, 1.0e+129]'
exp = iv.exp
assert iv.nstr(iv.exp(mpi('5000.1')), n, mode='diff') == '3.2797365856787867069110487[0926, 1191]e+2171'
iv.dps = 15
def test_mpi_from_str():
iv.dps = 15
assert iv.convert('1.5 +- 0.5') == mpi(mpf('1.0'), mpf('2.0'))
assert mpi(1, 2) in iv.convert('1.5 (33.33333333333333333333333333333%)')
assert iv.convert('[1, 2]') == mpi(1, 2)
assert iv.convert('1[2, 3]') == mpi(12, 13)
assert iv.convert('1.[23,46]e-8') == mpi('1.23e-8', '1.46e-8')
assert iv.convert('12[3.4,5.9]e4') == mpi('123.4e+4', '125.9e4')
def test_interval_gamma():
mp.dps = 15
iv.dps = 15
# TODO: need many more tests
assert iv.rgamma(0) == 0
assert iv.fac(0) == 1
assert iv.fac(1) == 1
assert iv.fac(2) == 2
assert iv.fac(3) == 6
assert iv.gamma(0) == [-inf,inf]
assert iv.gamma(1) == 1
assert iv.gamma(2) == 1
assert iv.gamma(3) == 2
assert -3.5449077018110320546 in iv.gamma(-0.5)
assert iv.loggamma(1) == 0
assert iv.loggamma(2) == 0
assert 0.69314718055994530942 in iv.loggamma(3)
# Test tight log-gamma endpoints based on monotonicity
xs = [iv.mpc([2,3],[1,4]),
iv.mpc([2,3],[-4,-1]),
iv.mpc([2,3],[-1,4]),
iv.mpc([2,3],[-4,1]),
iv.mpc([2,3],[-4,4]),
iv.mpc([-3,-2],[2,4]),
iv.mpc([-3,-2],[-4,-2])]
for x in xs:
ys = [mp.loggamma(mp.mpc(x.a,x.c)),
mp.loggamma(mp.mpc(x.b,x.c)),
mp.loggamma(mp.mpc(x.a,x.d)),
mp.loggamma(mp.mpc(x.b,x.d))]
if 0 in x.imag:
ys += [mp.loggamma(x.a), mp.loggamma(x.b)]
min_real = min([y.real for y in ys])
max_real = max([y.real for y in ys])
min_imag = min([y.imag for y in ys])
max_imag = max([y.imag for y in ys])
z = iv.loggamma(x)
assert z.a.ae(min_real)
assert z.b.ae(max_real)
assert z.c.ae(min_imag)
assert z.d.ae(max_imag)
def test_interval_conversions():
mp.dps = 15
iv.dps = 15
for a, b in ((-0.0, 0), (0.0, 0.5), (1.0, 1), \
('-inf', 20.5), ('-inf', float(sqrt(2)))):
r = mpi(a, b)
assert int(r.b) == int(b)
assert float(r.a) == float(a)
assert float(r.b) == float(b)
assert complex(r.a) == complex(a)
assert complex(r.b) == complex(b)

View File

@ -0,0 +1,153 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
from mpmath import mp
from mpmath import libmp
xrange = libmp.backend.xrange
# Attention:
# These tests run with 15-20 decimal digits precision. For higher precision the
# working precision must be raised.
def test_levin_0():
mp.dps = 17
eps = mp.mpf(mp.eps)
with mp.extraprec(2 * mp.prec):
L = mp.levin(method = "levin", variant = "u")
S, s, n = [], 0, 1
while 1:
s += mp.one / (n * n)
n += 1
S.append(s)
v, e = L.update_psum(S)
if e < eps:
break
if n > 1000: raise RuntimeError("iteration limit exceeded")
eps = mp.exp(0.9 * mp.log(eps))
err = abs(v - mp.pi ** 2 / 6)
assert err < eps
w = mp.nsum(lambda n: 1/(n * n), [1, mp.inf], method = "levin", levin_variant = "u")
err = abs(v - w)
assert err < eps
def test_levin_1():
mp.dps = 17
eps = mp.mpf(mp.eps)
with mp.extraprec(2 * mp.prec):
L = mp.levin(method = "levin", variant = "v")
A, n = [], 1
while 1:
s = mp.mpf(n) ** (2 + 3j)
n += 1
A.append(s)
v, e = L.update(A)
if e < eps:
break
if n > 1000: raise RuntimeError("iteration limit exceeded")
eps = mp.exp(0.9 * mp.log(eps))
err = abs(v - mp.zeta(-2-3j))
assert err < eps
w = mp.nsum(lambda n: n ** (2 + 3j), [1, mp.inf], method = "levin", levin_variant = "v")
err = abs(v - w)
assert err < eps
def test_levin_2():
# [2] A. Sidi - "Pratical Extrapolation Methods" p.373
mp.dps = 17
z=mp.mpf(10)
eps = mp.mpf(mp.eps)
with mp.extraprec(2 * mp.prec):
L = mp.levin(method = "sidi", variant = "t")
n = 0
while 1:
s = (-1)**n * mp.fac(n) * z ** (-n)
v, e = L.step(s)
n += 1
if e < eps:
break
if n > 1000: raise RuntimeError("iteration limit exceeded")
eps = mp.exp(0.9 * mp.log(eps))
exact = mp.quad(lambda x: mp.exp(-x)/(1+x/z),[0,mp.inf])
# there is also a symbolic expression for the integral:
# exact = z * mp.exp(z) * mp.expint(1,z)
err = abs(v - exact)
assert err < eps
w = mp.nsum(lambda n: (-1) ** n * mp.fac(n) * z ** (-n), [0, mp.inf], method = "sidi", levin_variant = "t")
assert err < eps
def test_levin_3():
mp.dps = 17
z=mp.mpf(2)
eps = mp.mpf(mp.eps)
with mp.extraprec(7*mp.prec): # we need copious amount of precision to sum this highly divergent series
L = mp.levin(method = "levin", variant = "t")
n, s = 0, 0
while 1:
s += (-z)**n * mp.fac(4 * n) / (mp.fac(n) * mp.fac(2 * n) * (4 ** n))
n += 1
v, e = L.step_psum(s)
if e < eps:
break
if n > 1000: raise RuntimeError("iteration limit exceeded")
eps = mp.exp(0.8 * mp.log(eps))
exact = mp.quad(lambda x: mp.exp( -x * x / 2 - z * x ** 4), [0,mp.inf]) * 2 / mp.sqrt(2 * mp.pi)
# there is also a symbolic expression for the integral:
# exact = mp.exp(mp.one / (32 * z)) * mp.besselk(mp.one / 4, mp.one / (32 * z)) / (4 * mp.sqrt(z * mp.pi))
err = abs(v - exact)
assert err < eps
w = mp.nsum(lambda n: (-z)**n * mp.fac(4 * n) / (mp.fac(n) * mp.fac(2 * n) * (4 ** n)), [0, mp.inf], method = "levin", levin_variant = "t", workprec = 8*mp.prec, steps = [2] + [1 for x in xrange(1000)])
err = abs(v - w)
assert err < eps
def test_levin_nsum():
mp.dps = 17
with mp.extraprec(mp.prec):
z = mp.mpf(10) ** (-10)
a = mp.nsum(lambda n: n**(-(1+z)), [1, mp.inf], method = "l") - 1 / z
assert abs(a - mp.euler) < 1e-10
eps = mp.exp(0.8 * mp.log(mp.eps))
a = mp.nsum(lambda n: (-1)**(n-1) / n, [1, mp.inf], method = "sidi")
assert abs(a - mp.log(2)) < eps
z = 2 + 1j
f = lambda n: mp.rf(2 / mp.mpf(3), n) * mp.rf(4 / mp.mpf(3), n) * z**n / (mp.rf(1 / mp.mpf(3), n) * mp.fac(n))
v = mp.nsum(f, [0, mp.inf], method = "levin", steps = [10 for x in xrange(1000)])
exact = mp.hyp2f1(2 / mp.mpf(3), 4 / mp.mpf(3), 1 / mp.mpf(3), z)
assert abs(exact - v) < eps
def test_cohen_alt_0():
mp.dps = 17
AC = mp.cohen_alt()
S, s, n = [], 0, 1
while 1:
s += -((-1) ** n) * mp.one / (n * n)
n += 1
S.append(s)
v, e = AC.update_psum(S)
if e < mp.eps:
break
if n > 1000: raise RuntimeError("iteration limit exceeded")
eps = mp.exp(0.9 * mp.log(mp.eps))
err = abs(v - mp.pi ** 2 / 12)
assert err < eps
def test_cohen_alt_1():
mp.dps = 17
A = []
AC = mp.cohen_alt()
n = 1
while 1:
A.append( mp.loggamma(1 + mp.one / (2 * n - 1)))
A.append(-mp.loggamma(1 + mp.one / (2 * n)))
n += 1
v, e = AC.update(A)
if e < mp.eps:
break
if n > 1000: raise RuntimeError("iteration limit exceeded")
v = mp.exp(v)
err = abs(v - 1.06215090557106)
assert err < 1e-12

View File

@ -0,0 +1,332 @@
# TODO: don't use round
from __future__ import division
import pytest
from mpmath import *
xrange = libmp.backend.xrange
# XXX: these shouldn't be visible(?)
LU_decomp = mp.LU_decomp
L_solve = mp.L_solve
U_solve = mp.U_solve
householder = mp.householder
improve_solution = mp.improve_solution
A1 = matrix([[3, 1, 6],
[2, 1, 3],
[1, 1, 1]])
b1 = [2, 7, 4]
A2 = matrix([[ 2, -1, -1, 2],
[ 6, -2, 3, -1],
[-4, 2, 3, -2],
[ 2, 0, 4, -3]])
b2 = [3, -3, -2, -1]
A3 = matrix([[ 1, 0, -1, -1, 0],
[ 0, 1, 1, 0, -1],
[ 4, -5, 2, 0, 0],
[ 0, 0, -2, 9,-12],
[ 0, 5, 0, 0, 12]])
b3 = [0, 0, 0, 0, 50]
A4 = matrix([[10.235, -4.56, 0., -0.035, 5.67],
[-2.463, 1.27, 3.97, -8.63, 1.08],
[-6.58, 0.86, -0.257, 9.32, -43.6 ],
[ 9.83, 7.39, -17.25, 0.036, 24.86],
[-9.31, 34.9, 78.56, 1.07, 65.8 ]])
b4 = [8.95, 20.54, 7.42, 5.60, 58.43]
A5 = matrix([[ 1, 2, -4],
[-2, -3, 5],
[ 3, 5, -8]])
A6 = matrix([[ 1.377360, 2.481400, 5.359190],
[ 2.679280, -1.229560, 25.560210],
[-1.225280+1.e6, 9.910180, -35.049900-1.e6]])
b6 = [23.500000, -15.760000, 2.340000]
A7 = matrix([[1, -0.5],
[2, 1],
[-2, 6]])
b7 = [3, 2, -4]
A8 = matrix([[1, 2, 3],
[-1, 0, 1],
[-1, -2, -1],
[1, 0, -1]])
b8 = [1, 2, 3, 4]
A9 = matrix([[ 4, 2, -2],
[ 2, 5, -4],
[-2, -4, 5.5]])
b9 = [10, 16, -15.5]
A10 = matrix([[1.0 + 1.0j, 2.0, 2.0],
[4.0, 5.0, 6.0],
[7.0, 8.0, 9.0]])
b10 = [1.0, 1.0 + 1.0j, 1.0]
def test_LU_decomp():
A = A3.copy()
b = b3
A, p = LU_decomp(A)
y = L_solve(A, b, p)
x = U_solve(A, y)
assert p == [2, 1, 2, 3]
assert [round(i, 14) for i in x] == [3.78953107960742, 2.9989094874591098,
-0.081788440567070006, 3.8713195201744801, 2.9171210468920399]
A = A4.copy()
b = b4
A, p = LU_decomp(A)
y = L_solve(A, b, p)
x = U_solve(A, y)
assert p == [0, 3, 4, 3]
assert [round(i, 14) for i in x] == [2.6383625899619201, 2.6643834462368399,
0.79208015947958998, -2.5088376454101899, -1.0567657691375001]
A = randmatrix(3)
bak = A.copy()
LU_decomp(A, overwrite=1)
assert A != bak
def test_inverse():
for A in [A1, A2, A5]:
inv = inverse(A)
assert mnorm(A*inv - eye(A.rows), 1) < 1.e-14
def test_householder():
mp.dps = 15
A, b = A8, b8
H, p, x, r = householder(extend(A, b))
assert H == matrix(
[[mpf('3.0'), mpf('-2.0'), mpf('-1.0'), 0],
[-1.0,mpf('3.333333333333333'),mpf('-2.9999999999999991'),mpf('2.0')],
[-1.0, mpf('-0.66666666666666674'),mpf('2.8142135623730948'),
mpf('-2.8284271247461898')],
[1.0, mpf('-1.3333333333333333'),mpf('-0.20000000000000018'),
mpf('4.2426406871192857')]])
assert p == [-2, -2, mpf('-1.4142135623730949')]
assert round(norm(r, 2), 10) == 4.2426406870999998
y = [102.102, 58.344, 36.463, 24.310, 17.017, 12.376, 9.282, 7.140, 5.610,
4.488, 3.6465, 3.003]
def coeff(n):
# similiar to Hilbert matrix
A = []
for i in range(1, 13):
A.append([1. / (i + j - 1) for j in range(1, n + 1)])
return matrix(A)
residuals = []
refres = []
for n in range(2, 7):
A = coeff(n)
H, p, x, r = householder(extend(A, y))
x = matrix(x)
y = matrix(y)
residuals.append(norm(r, 2))
refres.append(norm(residual(A, x, y), 2))
assert [round(res, 10) for res in residuals] == [15.1733888877,
0.82378073210000002, 0.302645887, 0.0260109244,
0.00058653999999999998]
assert norm(matrix(residuals) - matrix(refres), inf) < 1.e-13
def hilbert_cmplx(n):
# Complexified Hilbert matrix
A = hilbert(2*n,n)
v = randmatrix(2*n, 2, min=-1, max=1)
v = v.apply(lambda x: exp(1J*pi()*x))
A = diag(v[:,0])*A*diag(v[:n,1])
return A
residuals_cmplx = []
refres_cmplx = []
for n in range(2, 10):
A = hilbert_cmplx(n)
H, p, x, r = householder(A.copy())
residuals_cmplx.append(norm(r, 2))
refres_cmplx.append(norm(residual(A[:,:n-1], x, A[:,n-1]), 2))
assert norm(matrix(residuals_cmplx) - matrix(refres_cmplx), inf) < 1.e-13
def test_factorization():
A = randmatrix(5)
P, L, U = lu(A)
assert mnorm(P*A - L*U, 1) < 1.e-15
def test_solve():
assert norm(residual(A6, lu_solve(A6, b6), b6), inf) < 1.e-10
assert norm(residual(A7, lu_solve(A7, b7), b7), inf) < 1.5
assert norm(residual(A8, lu_solve(A8, b8), b8), inf) <= 3 + 1.e-10
assert norm(residual(A6, qr_solve(A6, b6)[0], b6), inf) < 1.e-10
assert norm(residual(A7, qr_solve(A7, b7)[0], b7), inf) < 1.5
assert norm(residual(A8, qr_solve(A8, b8)[0], b8), 2) <= 4.3
assert norm(residual(A10, lu_solve(A10, b10), b10), 2) < 1.e-10
assert norm(residual(A10, qr_solve(A10, b10)[0], b10), 2) < 1.e-10
def test_solve_overdet_complex():
A = matrix([[1, 2j], [3, 4j], [5, 6]])
b = matrix([1 + j, 2, -j])
assert norm(residual(A, lu_solve(A, b), b)) < 1.0208
def test_singular():
mp.dps = 15
A = [[5.6, 1.2], [7./15, .1]]
B = repr(zeros(2))
b = [1, 2]
for i in ['lu_solve(%s, %s)' % (A, b), 'lu_solve(%s, %s)' % (B, b),
'qr_solve(%s, %s)' % (A, b), 'qr_solve(%s, %s)' % (B, b)]:
pytest.raises((ZeroDivisionError, ValueError), lambda: eval(i))
def test_cholesky():
assert fp.cholesky(fp.matrix(A9)) == fp.matrix([[2, 0, 0], [1, 2, 0], [-1, -3/2, 3/2]])
x = fp.cholesky_solve(A9, b9)
assert fp.norm(fp.residual(A9, x, b9), fp.inf) == 0
def test_det():
assert det(A1) == 1
assert round(det(A2), 14) == 8
assert round(det(A3)) == 1834
assert round(det(A4)) == 4443376
assert det(A5) == 1
assert round(det(A6)) == 78356463
assert det(zeros(3)) == 0
def test_cond():
mp.dps = 15
A = matrix([[1.2969, 0.8648], [0.2161, 0.1441]])
assert cond(A, lambda x: mnorm(x,1)) == mpf('327065209.73817754')
assert cond(A, lambda x: mnorm(x,inf)) == mpf('327065209.73817754')
assert cond(A, lambda x: mnorm(x,'F')) == mpf('249729266.80008656')
@extradps(50)
def test_precision():
A = randmatrix(10, 10)
assert mnorm(inverse(inverse(A)) - A, 1) < 1.e-45
def test_interval_matrix():
mp.dps = 15
iv.dps = 15
a = iv.matrix([['0.1','0.3','1.0'],['7.1','5.5','4.8'],['3.2','4.4','5.6']])
b = iv.matrix(['4','0.6','0.5'])
c = iv.lu_solve(a, b)
assert c[0].delta < 1e-13
assert c[1].delta < 1e-13
assert c[2].delta < 1e-13
assert 5.25823271130625686059275 in c[0]
assert -13.155049396267837541163 in c[1]
assert 7.42069154774972557628979 in c[2]
def test_LU_cache():
A = randmatrix(3)
LU = LU_decomp(A)
assert A._LU == LU_decomp(A)
A[0,0] = -1000
assert A._LU is None
def test_improve_solution():
A = randmatrix(5, min=1e-20, max=1e20)
b = randmatrix(5, 1, min=-1000, max=1000)
x1 = lu_solve(A, b) + randmatrix(5, 1, min=-1e-5, max=1.e-5)
x2 = improve_solution(A, x1, b)
assert norm(residual(A, x2, b), 2) < norm(residual(A, x1, b), 2)
def test_exp_pade():
for i in range(3):
dps = 15
extra = 15
mp.dps = dps + extra
dm = 0
N = 3
dg = range(1,N+1)
a = diag(dg)
expa = diag([exp(x) for x in dg])
# choose a random matrix not close to be singular
# to avoid adding too much extra precision in computing
# m**-1 * M * m
while abs(dm) < 0.01:
m = randmatrix(N)
dm = det(m)
m = m/dm
a1 = m**-1 * a * m
e2 = m**-1 * expa * m
mp.dps = dps
e1 = expm(a1, method='pade')
mp.dps = dps + extra
d = e2 - e1
#print d
mp.dps = dps
assert norm(d, inf).ae(0)
mp.dps = 15
def test_qr():
mp.dps = 15 # used default value for dps
lowlimit = -9 # lower limit of matrix element value
uplimit = 9 # uppter limit of matrix element value
maxm = 4 # max matrix size
flg = False # toggle to create real vs complex matrix
zero = mpf('0.0')
for k in xrange(0,10):
exdps = 0
mode = 'full'
flg = bool(k % 2)
# generate arbitrary matrix size (2 to maxm)
num1 = nint(maxm*rand())
num2 = nint(maxm*rand())
m = int(max(num1, num2))
n = int(min(num1, num2))
# create matrix
A = mp.matrix(m,n)
# populate matrix values with arbitrary integers
if flg:
flg = False
dtype = 'complex'
for j in xrange(0,n):
for i in xrange(0,m):
val = nint(lowlimit + (uplimit-lowlimit)*rand())
val2 = nint(lowlimit + (uplimit-lowlimit)*rand())
A[i,j] = mpc(val, val2)
else:
flg = True
dtype = 'real'
for j in xrange(0,n):
for i in xrange(0,m):
val = nint(lowlimit + (uplimit-lowlimit)*rand())
A[i,j] = mpf(val)
# perform A -> QR decomposition
Q, R = qr(A, mode, edps = exdps)
#print('\n\n A = \n', nstr(A, 4))
#print('\n Q = \n', nstr(Q, 4))
#print('\n R = \n', nstr(R, 4))
#print('\n Q*R = \n', nstr(Q*R, 4))
maxnorm = mpf('1.0E-11')
n1 = norm(A - Q * R)
#print '\n Norm of A - Q * R = ', n1
assert n1 <= maxnorm
if dtype == 'real':
n1 = norm(eye(m) - Q.T * Q)
#print ' Norm of I - Q.T * Q = ', n1
assert n1 <= maxnorm
n1 = norm(eye(m) - Q * Q.T)
#print ' Norm of I - Q * Q.T = ', n1
assert n1 <= maxnorm
if dtype == 'complex':
n1 = norm(eye(m) - Q.T * Q.conjugate())
#print ' Norm of I - Q.T * Q.conjugate() = ', n1
assert n1 <= maxnorm
n1 = norm(eye(m) - Q.conjugate() * Q.T)
#print ' Norm of I - Q.conjugate() * Q.T = ', n1
assert n1 <= maxnorm

View File

@ -0,0 +1,253 @@
import pytest
import sys
from mpmath import *
def test_matrix_basic():
A1 = matrix(3)
for i in range(3):
A1[i,i] = 1
assert A1 == eye(3)
assert A1 == matrix(A1)
A2 = matrix(3, 2)
assert not A2._matrix__data
A3 = matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
assert list(A3) == list(range(1, 10))
A3[1,1] = 0
assert not (1, 1) in A3._matrix__data
A4 = matrix([[1, 2, 3], [4, 5, 6]])
A5 = matrix([[6, -1], [3, 2], [0, -3]])
assert A4 * A5 == matrix([[12, -6], [39, -12]])
assert A1 * A3 == A3 * A1 == A3
pytest.raises(ValueError, lambda: A2*A2)
l = [[10, 20, 30], [40, 0, 60], [70, 80, 90]]
A6 = matrix(l)
assert A6.tolist() == l
assert A6 == eval(repr(A6))
A6 = fp.matrix(A6)
assert A6 == eval(repr(A6))
assert A6*1j == eval(repr(A6*1j))
assert A3 * 10 == 10 * A3 == A6
assert A2.rows == 3
assert A2.cols == 2
A3.rows = 2
A3.cols = 2
assert len(A3._matrix__data) == 3
assert A4 + A4 == 2*A4
pytest.raises(ValueError, lambda: A4 + A2)
assert sum(A1 - A1) == 0
A7 = matrix([[1, 2], [3, 4], [5, 6], [7, 8]])
x = matrix([10, -10])
assert A7*x == matrix([-10, -10, -10, -10])
A8 = ones(5)
assert sum((A8 + 1) - (2 - zeros(5))) == 0
assert (1 + ones(4)) / 2 - 1 == zeros(4)
assert eye(3)**10 == eye(3)
pytest.raises(ValueError, lambda: A7**2)
A9 = randmatrix(3)
A10 = matrix(A9)
A9[0,0] = -100
assert A9 != A10
assert nstr(A9)
def test_matmul():
"""
Test the PEP465 "@" matrix multiplication syntax.
To avoid syntax errors when importing this file in Python 3.5 and below, we have to use exec() - sorry for that.
"""
# TODO remove exec() wrapper as soon as we drop support for Python <= 3.5
if sys.hexversion < 0x30500f0:
# we are on Python < 3.5
pytest.skip("'@' (__matmul__) is only supported in Python 3.5 or newer")
A4 = matrix([[1, 2, 3], [4, 5, 6]])
A5 = matrix([[6, -1], [3, 2], [0, -3]])
exec("assert A4 @ A5 == A4 * A5")
def test_matrix_slices():
A = matrix([ [1, 2, 3],
[4, 5 ,6],
[7, 8 ,9]])
V = matrix([1,2,3,4,5])
# Get slice
assert A[:,:] == A
assert A[:,1] == matrix([[2],[5],[8]])
assert A[2,:] == matrix([[7, 8 ,9]])
assert A[1:3,1:3] == matrix([[5,6],[8,9]])
assert V[2:4] == matrix([3,4])
pytest.raises(IndexError, lambda: A[:,1:6])
# Assign slice with matrix
A1 = matrix(3)
A1[:,:] = A
assert A1[:,:] == matrix([[1, 2, 3],
[4, 5 ,6],
[7, 8 ,9]])
A1[0,:] = matrix([[10, 11, 12]])
assert A1 == matrix([ [10, 11, 12],
[4, 5 ,6],
[7, 8 ,9]])
A1[:,2] = matrix([[13], [14], [15]])
assert A1 == matrix([ [10, 11, 13],
[4, 5 ,14],
[7, 8 ,15]])
A1[:2,:2] = matrix([[16, 17], [18 , 19]])
assert A1 == matrix([ [16, 17, 13],
[18, 19 ,14],
[7, 8 ,15]])
V[1:3] = 10
assert V == matrix([1,10,10,4,5])
with pytest.raises(ValueError):
A1[2,:] = A[:,1]
with pytest.raises(IndexError):
A1[2,1:20] = A[:,:]
# Assign slice with scalar
A1[:,2] = 10
assert A1 == matrix([ [16, 17, 10],
[18, 19 ,10],
[7, 8 ,10]])
A1[:,:] = 40
for x in A1:
assert x == 40
def test_matrix_power():
A = matrix([[1, 2], [3, 4]])
assert A**2 == A*A
assert A**3 == A*A*A
assert A**-1 == inverse(A)
assert A**-2 == inverse(A*A)
def test_matrix_transform():
A = matrix([[1, 2], [3, 4], [5, 6]])
assert A.T == A.transpose() == matrix([[1, 3, 5], [2, 4, 6]])
swap_row(A, 1, 2)
assert A == matrix([[1, 2], [5, 6], [3, 4]])
l = [1, 2]
swap_row(l, 0, 1)
assert l == [2, 1]
assert extend(eye(3), [1,2,3]) == matrix([[1,0,0,1],[0,1,0,2],[0,0,1,3]])
def test_matrix_conjugate():
A = matrix([[1 + j, 0], [2, j]])
assert A.conjugate() == matrix([[mpc(1, -1), 0], [2, mpc(0, -1)]])
assert A.transpose_conj() == A.H == matrix([[mpc(1, -1), 2],
[0, mpc(0, -1)]])
def test_matrix_creation():
assert diag([1, 2, 3]) == matrix([[1, 0, 0], [0, 2, 0], [0, 0, 3]])
A1 = ones(2, 3)
assert A1.rows == 2 and A1.cols == 3
for a in A1:
assert a == 1
A2 = zeros(3, 2)
assert A2.rows == 3 and A2.cols == 2
for a in A2:
assert a == 0
assert randmatrix(10) != randmatrix(10)
one = mpf(1)
assert hilbert(3) == matrix([[one, one/2, one/3],
[one/2, one/3, one/4],
[one/3, one/4, one/5]])
def test_norms():
# matrix norms
A = matrix([[1, -2], [-3, -1], [2, 1]])
assert mnorm(A,1) == 6
assert mnorm(A,inf) == 4
assert mnorm(A,'F') == sqrt(20)
# vector norms
assert norm(-3) == 3
x = [1, -2, 7, -12]
assert norm(x, 1) == 22
assert round(norm(x, 2), 10) == 14.0712472795
assert round(norm(x, 10), 10) == 12.0054633727
assert norm(x, inf) == 12
def test_vector():
x = matrix([0, 1, 2, 3, 4])
assert x == matrix([[0], [1], [2], [3], [4]])
assert x[3] == 3
assert len(x._matrix__data) == 4
assert list(x) == list(range(5))
x[0] = -10
x[4] = 0
assert x[0] == -10
assert len(x) == len(x.T) == 5
assert x.T*x == matrix([[114]])
def test_matrix_copy():
A = ones(6)
B = A.copy()
C = +A
assert A == B
assert A == C
B[0,0] = 0
assert A != B
C[0,0] = 42
assert A != C
def test_matrix_numpy():
try:
import numpy
except ImportError:
return
l = [[1, 2], [3, 4], [5, 6]]
a = numpy.array(l)
assert matrix(l) == matrix(a)
def test_interval_matrix_scalar_mult():
"""Multiplication of iv.matrix and any scalar type"""
a = mpi(-1, 1)
b = a + a * 2j
c = mpf(42)
d = c + c * 2j
e = 1.234
f = fp.convert(e)
g = e + e * 3j
h = fp.convert(g)
M = iv.ones(1)
for x in [a, b, c, d, e, f, g, h]:
assert x * M == iv.matrix([x])
assert M * x == iv.matrix([x])
@pytest.mark.xfail()
def test_interval_matrix_matrix_mult():
"""Multiplication of iv.matrix and other matrix types"""
A = ones(1)
B = fp.ones(1)
M = iv.ones(1)
for X in [A, B, M]:
assert X * M == iv.matrix(X)
assert X * M == X
assert M * X == iv.matrix(X)
assert M * X == X
def test_matrix_conversion_to_iv():
# Test that matrices with foreign datatypes are properly converted
for other_type_eye in [eye(3), fp.eye(3), iv.eye(3)]:
A = iv.matrix(other_type_eye)
B = iv.eye(3)
assert type(A[0,0]) == type(B[0,0])
assert A.tolist() == B.tolist()
def test_interval_matrix_mult_bug():
# regression test for interval matrix multiplication:
# result must be nonzero-width and contain the exact result
x = convert('1.00000000000001') # note: this is implicitly rounded to some near mpf float value
A = matrix([[x]])
B = iv.matrix(A)
C = iv.matrix([[x]])
assert B == C
B = B * B
C = C * C
assert B == C
assert B[0, 0].delta > 1e-16
assert B[0, 0].delta < 3e-16
assert C[0, 0].delta > 1e-16
assert C[0, 0].delta < 3e-16
assert mp.mpf('1.00000000000001998401444325291756783368705994138804689654') in B[0, 0]
assert mp.mpf('1.00000000000001998401444325291756783368705994138804689654') in C[0, 0]
# the following caused an error before the bug was fixed
assert iv.matrix(mp.eye(2)) * (iv.ones(2) + mpi(1, 2)) == iv.matrix([[mpi(2, 3), mpi(2, 3)], [mpi(2, 3), mpi(2, 3)]])

View File

@ -0,0 +1,7 @@
from mpmath.libmp import *
from mpmath import *
def test_newstyle_classes():
for cls in [mp, fp, iv, mpf, mpc]:
for s in cls.__class__.__mro__:
assert isinstance(s, type)

View File

@ -0,0 +1,73 @@
#from mpmath.calculus import ODE_step_euler, ODE_step_rk4, odeint, arange
from mpmath import odefun, cos, sin, mpf, sinc, mp
'''
solvers = [ODE_step_euler, ODE_step_rk4]
def test_ode1():
"""
Let's solve:
x'' + w**2 * x = 0
i.e. x1 = x, x2 = x1':
x1' = x2
x2' = -x1
"""
def derivs((x1, x2), t):
return x2, -x1
for solver in solvers:
t = arange(0, 3.1415926, 0.005)
sol = odeint(derivs, (0., 1.), t, solver)
x1 = [a[0] for a in sol]
x2 = [a[1] for a in sol]
# the result is x1 = sin(t), x2 = cos(t)
# let's just check the end points for t = pi
assert abs(x1[-1]) < 1e-2
assert abs(x2[-1] - (-1)) < 1e-2
def test_ode2():
"""
Let's solve:
x' - x = 0
i.e. x = exp(x)
"""
def derivs((x), t):
return x
for solver in solvers:
t = arange(0, 1, 1e-3)
sol = odeint(derivs, (1.,), t, solver)
x = [a[0] for a in sol]
# the result is x = exp(t)
# let's just check the end point for t = 1, i.e. x = e
assert abs(x[-1] - 2.718281828) < 1e-2
'''
def test_odefun_rational():
mp.dps = 15
# A rational function
f = lambda t: 1/(1+mpf(t)**2)
g = odefun(lambda x, y: [-2*x*y[0]**2], 0, [f(0)])
assert f(2).ae(g(2)[0])
def test_odefun_sinc_large():
mp.dps = 15
# Sinc function; test for large x
f = sinc
g = odefun(lambda x, y: [(cos(x)-y[0])/x], 1, [f(1)], tol=0.01, degree=5)
assert abs(f(100) - g(100)[0])/f(100) < 0.01
def test_odefun_harmonic():
mp.dps = 15
# Harmonic oscillator
f = odefun(lambda x, y: [-y[1], y[0]], 0, [1, 0])
for x in [0, 1, 2.5, 8, 3.7]: # we go back to 3.7 to check caching
c, s = f(x)
assert c.ae(cos(x))
assert s.ae(sin(x))

View File

@ -0,0 +1,27 @@
import os
import tempfile
import pickle
from mpmath import *
def pickler(obj):
fn = tempfile.mktemp()
f = open(fn, 'wb')
pickle.dump(obj, f)
f.close()
f = open(fn, 'rb')
obj2 = pickle.load(f)
f.close()
os.remove(fn)
return obj2
def test_pickle():
obj = mpf('0.5')
assert obj == pickler(obj)
obj = mpc('0.5','0.2')
assert obj == pickler(obj)

View File

@ -0,0 +1,156 @@
from mpmath import *
from mpmath.libmp import *
import random
def test_fractional_pow():
mp.dps = 15
assert mpf(16) ** 2.5 == 1024
assert mpf(64) ** 0.5 == 8
assert mpf(64) ** -0.5 == 0.125
assert mpf(16) ** -2.5 == 0.0009765625
assert (mpf(10) ** 0.5).ae(3.1622776601683791)
assert (mpf(10) ** 2.5).ae(316.2277660168379)
assert (mpf(10) ** -0.5).ae(0.31622776601683794)
assert (mpf(10) ** -2.5).ae(0.0031622776601683794)
assert (mpf(10) ** 0.3).ae(1.9952623149688795)
assert (mpf(10) ** -0.3).ae(0.50118723362727224)
def test_pow_integer_direction():
"""
Test that inexact integer powers are rounded in the right
direction.
"""
random.seed(1234)
for prec in [10, 53, 200]:
for i in range(50):
a = random.randint(1<<(prec-1), 1<<prec)
b = random.randint(2, 100)
ab = a**b
# note: could actually be exact, but that's very unlikely!
assert to_int(mpf_pow(from_int(a), from_int(b), prec, round_down)) < ab
assert to_int(mpf_pow(from_int(a), from_int(b), prec, round_up)) > ab
def test_pow_epsilon_rounding():
"""
Stress test directed rounding for powers with integer exponents.
Basically, we look at the following cases:
>>> 1.0001 ** -5 # doctest: +SKIP
0.99950014996500702
>>> 0.9999 ** -5 # doctest: +SKIP
1.000500150035007
>>> (-1.0001) ** -5 # doctest: +SKIP
-0.99950014996500702
>>> (-0.9999) ** -5 # doctest: +SKIP
-1.000500150035007
>>> 1.0001 ** -6 # doctest: +SKIP
0.99940020994401269
>>> 0.9999 ** -6 # doctest: +SKIP
1.0006002100560125
>>> (-1.0001) ** -6 # doctest: +SKIP
0.99940020994401269
>>> (-0.9999) ** -6 # doctest: +SKIP
1.0006002100560125
etc.
We run the tests with values a very small epsilon away from 1:
small enough that the result is indistinguishable from 1 when
rounded to nearest at the output precision. We check that the
result is not erroneously rounded to 1 in cases where the
rounding should be done strictly away from 1.
"""
def powr(x, n, r):
return make_mpf(mpf_pow_int(x._mpf_, n, mp.prec, r))
for (inprec, outprec) in [(100, 20), (5000, 3000)]:
mp.prec = inprec
pos10001 = mpf(1) + mpf(2)**(-inprec+5)
pos09999 = mpf(1) - mpf(2)**(-inprec+5)
neg10001 = -pos10001
neg09999 = -pos09999
mp.prec = outprec
r = round_up
assert powr(pos10001, 5, r) > 1
assert powr(pos09999, 5, r) == 1
assert powr(neg10001, 5, r) < -1
assert powr(neg09999, 5, r) == -1
assert powr(pos10001, 6, r) > 1
assert powr(pos09999, 6, r) == 1
assert powr(neg10001, 6, r) > 1
assert powr(neg09999, 6, r) == 1
assert powr(pos10001, -5, r) == 1
assert powr(pos09999, -5, r) > 1
assert powr(neg10001, -5, r) == -1
assert powr(neg09999, -5, r) < -1
assert powr(pos10001, -6, r) == 1
assert powr(pos09999, -6, r) > 1
assert powr(neg10001, -6, r) == 1
assert powr(neg09999, -6, r) > 1
r = round_down
assert powr(pos10001, 5, r) == 1
assert powr(pos09999, 5, r) < 1
assert powr(neg10001, 5, r) == -1
assert powr(neg09999, 5, r) > -1
assert powr(pos10001, 6, r) == 1
assert powr(pos09999, 6, r) < 1
assert powr(neg10001, 6, r) == 1
assert powr(neg09999, 6, r) < 1
assert powr(pos10001, -5, r) < 1
assert powr(pos09999, -5, r) == 1
assert powr(neg10001, -5, r) > -1
assert powr(neg09999, -5, r) == -1
assert powr(pos10001, -6, r) < 1
assert powr(pos09999, -6, r) == 1
assert powr(neg10001, -6, r) < 1
assert powr(neg09999, -6, r) == 1
r = round_ceiling
assert powr(pos10001, 5, r) > 1
assert powr(pos09999, 5, r) == 1
assert powr(neg10001, 5, r) == -1
assert powr(neg09999, 5, r) > -1
assert powr(pos10001, 6, r) > 1
assert powr(pos09999, 6, r) == 1
assert powr(neg10001, 6, r) > 1
assert powr(neg09999, 6, r) == 1
assert powr(pos10001, -5, r) == 1
assert powr(pos09999, -5, r) > 1
assert powr(neg10001, -5, r) > -1
assert powr(neg09999, -5, r) == -1
assert powr(pos10001, -6, r) == 1
assert powr(pos09999, -6, r) > 1
assert powr(neg10001, -6, r) == 1
assert powr(neg09999, -6, r) > 1
r = round_floor
assert powr(pos10001, 5, r) == 1
assert powr(pos09999, 5, r) < 1
assert powr(neg10001, 5, r) < -1
assert powr(neg09999, 5, r) == -1
assert powr(pos10001, 6, r) == 1
assert powr(pos09999, 6, r) < 1
assert powr(neg10001, 6, r) == 1
assert powr(neg09999, 6, r) < 1
assert powr(pos10001, -5, r) < 1
assert powr(pos09999, -5, r) == 1
assert powr(neg10001, -5, r) == -1
assert powr(neg09999, -5, r) < -1
assert powr(pos10001, -6, r) < 1
assert powr(pos09999, -6, r) == 1
assert powr(neg10001, -6, r) < 1
assert powr(neg09999, -6, r) == 1
mp.dps = 15

View File

@ -0,0 +1,95 @@
import pytest
from mpmath import *
def ae(a, b):
return abs(a-b) < 10**(-mp.dps+5)
def test_basic_integrals():
for prec in [15, 30, 100]:
mp.dps = prec
assert ae(quadts(lambda x: x**3 - 3*x**2, [-2, 4]), -12)
assert ae(quadgl(lambda x: x**3 - 3*x**2, [-2, 4]), -12)
assert ae(quadts(sin, [0, pi]), 2)
assert ae(quadts(sin, [0, 2*pi]), 0)
assert ae(quadts(exp, [-inf, -1]), 1/e)
assert ae(quadts(lambda x: exp(-x), [0, inf]), 1)
assert ae(quadts(lambda x: exp(-x*x), [-inf, inf]), sqrt(pi))
assert ae(quadts(lambda x: 1/(1+x*x), [-1, 1]), pi/2)
assert ae(quadts(lambda x: 1/(1+x*x), [-inf, inf]), pi)
assert ae(quadts(lambda x: 2*sqrt(1-x*x), [-1, 1]), pi)
mp.dps = 15
def test_multiple_intervals():
y,err = quad(lambda x: sign(x), [-0.5, 0.9, 1], maxdegree=2, error=True)
assert abs(y-0.5) < 2*err
def test_quad_symmetry():
assert quadts(sin, [-1, 1]) == 0
assert quadgl(sin, [-1, 1]) == 0
def test_quad_infinite_mirror():
# Check mirrored infinite interval
assert ae(quad(lambda x: exp(-x*x), [inf,-inf]), -sqrt(pi))
assert ae(quad(lambda x: exp(x), [0,-inf]), -1)
def test_quadgl_linear():
assert quadgl(lambda x: x, [0, 1], maxdegree=1).ae(0.5)
def test_complex_integration():
assert quadts(lambda x: x, [0, 1+j]).ae(j)
def test_quadosc():
mp.dps = 15
assert quadosc(lambda x: sin(x)/x, [0, inf], period=2*pi).ae(pi/2)
# Double integrals
def test_double_trivial():
assert ae(quadts(lambda x, y: x, [0, 1], [0, 1]), 0.5)
assert ae(quadts(lambda x, y: x, [-1, 1], [-1, 1]), 0.0)
def test_double_1():
assert ae(quadts(lambda x, y: cos(x+y/2), [-pi/2, pi/2], [0, pi]), 4)
def test_double_2():
assert ae(quadts(lambda x, y: (x-1)/((1-x*y)*log(x*y)), [0, 1], [0, 1]), euler)
def test_double_3():
assert ae(quadts(lambda x, y: 1/sqrt(1+x*x+y*y), [-1, 1], [-1, 1]), 4*log(2+sqrt(3))-2*pi/3)
def test_double_4():
assert ae(quadts(lambda x, y: 1/(1-x*x * y*y), [0, 1], [0, 1]), pi**2 / 8)
def test_double_5():
assert ae(quadts(lambda x, y: 1/(1-x*y), [0, 1], [0, 1]), pi**2 / 6)
def test_double_6():
assert ae(quadts(lambda x, y: exp(-(x+y)), [0, inf], [0, inf]), 1)
def test_double_7():
assert ae(quadts(lambda x, y: exp(-x*x-y*y), [-inf, inf], [-inf, inf]), pi)
# Test integrals from "Experimentation in Mathematics" by Borwein,
# Bailey & Girgensohn
def test_expmath_integrals():
for prec in [15, 30, 50]:
mp.dps = prec
assert ae(quadts(lambda x: x/sinh(x), [0, inf]), pi**2 / 4)
assert ae(quadts(lambda x: log(x)**2 / (1+x**2), [0, inf]), pi**3 / 8)
assert ae(quadts(lambda x: (1+x**2)/(1+x**4), [0, inf]), pi/sqrt(2))
assert ae(quadts(lambda x: log(x)/cosh(x)**2, [0, inf]), log(pi)-2*log(2)-euler)
assert ae(quadts(lambda x: log(1+x**3)/(1-x+x**2), [0, inf]), 2*pi*log(3)/sqrt(3))
assert ae(quadts(lambda x: log(x)**2 / (x**2+x+1), [0, 1]), 8*pi**3 / (81*sqrt(3)))
assert ae(quadts(lambda x: log(cos(x))**2, [0, pi/2]), pi/2 * (log(2)**2+pi**2/12))
assert ae(quadts(lambda x: x**2 / sin(x)**2, [0, pi/2]), pi*log(2))
assert ae(quadts(lambda x: x**2/sqrt(exp(x)-1), [0, inf]), 4*pi*(log(2)**2 + pi**2/12))
assert ae(quadts(lambda x: x*exp(-x)*sqrt(1-exp(-2*x)), [0, inf]), pi*(1+2*log(2))/8)
mp.dps = 15
# Do not reach full accuracy
@pytest.mark.xfail
def test_expmath_fail():
assert ae(quadts(lambda x: sqrt(tan(x)), [0, pi/2]), pi*sqrt(2)/2)
assert ae(quadts(lambda x: atan(x)/(x*sqrt(1-x**2)), [0, 1]), pi*log(1+sqrt(2))/2)
assert ae(quadts(lambda x: log(1+x**2)/x**2, [0, 1]), pi/2-log(2))
assert ae(quadts(lambda x: x**2/((1+x**4)*sqrt(1-x**4)), [0, 1]), pi/8)

View File

@ -0,0 +1,91 @@
import pytest
from mpmath import *
from mpmath.calculus.optimization import Secant, Muller, Bisection, Illinois, \
Pegasus, Anderson, Ridder, ANewton, Newton, MNewton, MDNewton
def test_findroot():
# old tests, assuming secant
mp.dps = 15
assert findroot(lambda x: 4*x-3, mpf(5)).ae(0.75)
assert findroot(sin, mpf(3)).ae(pi)
assert findroot(sin, (mpf(3), mpf(3.14))).ae(pi)
assert findroot(lambda x: x*x+1, mpc(2+2j)).ae(1j)
# test all solvers with 1 starting point
f = lambda x: cos(x)
for solver in [Newton, Secant, MNewton, Muller, ANewton]:
x = findroot(f, 2., solver=solver)
assert abs(f(x)) < eps
# test all solvers with interval of 2 points
for solver in [Secant, Muller, Bisection, Illinois, Pegasus, Anderson,
Ridder]:
x = findroot(f, (1., 2.), solver=solver)
assert abs(f(x)) < eps
# test types
f = lambda x: (x - 2)**2
assert isinstance(findroot(f, 1, tol=1e-10), mpf)
assert isinstance(iv.findroot(f, 1., tol=1e-10), iv.mpf)
assert isinstance(fp.findroot(f, 1, tol=1e-10), float)
assert isinstance(fp.findroot(f, 1+0j, tol=1e-10), complex)
# issue 401
with pytest.raises(ValueError):
with workprec(2):
findroot(lambda x: x**2 - 4456178*x + 60372201703370,
mpc(real='5.278e+13', imag='-5.278e+13'))
# issue 192
with pytest.raises(ValueError):
findroot(lambda x: -1, 0)
# issue 387
with pytest.raises(ValueError):
findroot(lambda p: (1 - p)**30 - 1, 0.9)
def test_bisection():
# issue 273
assert findroot(lambda x: x**2-1,(0,2),solver='bisect') == 1
def test_mnewton():
f = lambda x: polyval([1,3,3,1],x)
x = findroot(f, -0.9, solver='mnewton')
assert abs(f(x)) < eps
def test_anewton():
f = lambda x: (x - 2)**100
x = findroot(f, 1., solver=ANewton)
assert abs(f(x)) < eps
def test_muller():
f = lambda x: (2 + x)**3 + 2
x = findroot(f, 1., solver=Muller)
assert abs(f(x)) < eps
def test_multiplicity():
for i in range(1, 5):
assert multiplicity(lambda x: (x - 1)**i, 1) == i
assert multiplicity(lambda x: x**2, 1) == 0
def test_multidimensional():
def f(*x):
return [3*x[0]**2-2*x[1]**2-1, x[0]**2-2*x[0]+x[1]**2+2*x[1]-8]
assert mnorm(jacobian(f, (1,-2)) - matrix([[6,8],[0,-2]]),1) < 1.e-7
for x, error in MDNewton(mp, f, (1,-2), verbose=0,
norm=lambda x: norm(x, inf)):
pass
assert norm(f(*x), 2) < 1e-14
# The Chinese mathematician Zhu Shijie was the very first to solve this
# nonlinear system 700 years ago
f1 = lambda x, y: -x + 2*y
f2 = lambda x, y: (x**2 + x*(y**2 - 2) - 4*y) / (x + 4)
f3 = lambda x, y: sqrt(x**2 + y**2)
def f(x, y):
f1x = f1(x, y)
return (f2(x, y) - f1x, f3(x, y) - f1x)
x = findroot(f, (10, 10))
assert [int(round(i)) for i in x] == [3, 4]
def test_trivial():
assert findroot(lambda x: 0, 1) == 1
assert findroot(lambda x: x, 0) == 0
#assert findroot(lambda x, y: x + y, (1, -1)) == (1, -1)

View File

@ -0,0 +1,113 @@
from mpmath import *
def test_special():
assert inf == inf
assert inf != -inf
assert -inf == -inf
assert inf != nan
assert nan != nan
assert isnan(nan)
assert --inf == inf
assert abs(inf) == inf
assert abs(-inf) == inf
assert abs(nan) != abs(nan)
assert isnan(inf - inf)
assert isnan(inf + (-inf))
assert isnan(-inf - (-inf))
assert isnan(inf + nan)
assert isnan(-inf + nan)
assert mpf(2) + inf == inf
assert 2 + inf == inf
assert mpf(2) - inf == -inf
assert 2 - inf == -inf
assert inf > 3
assert 3 < inf
assert 3 > -inf
assert -inf < 3
assert inf > mpf(3)
assert mpf(3) < inf
assert mpf(3) > -inf
assert -inf < mpf(3)
assert not (nan < 3)
assert not (nan > 3)
assert isnan(inf * 0)
assert isnan(-inf * 0)
assert inf * 3 == inf
assert inf * -3 == -inf
assert -inf * 3 == -inf
assert -inf * -3 == inf
assert inf * inf == inf
assert -inf * -inf == inf
assert isnan(nan / 3)
assert inf / -3 == -inf
assert inf / 3 == inf
assert 3 / inf == 0
assert -3 / inf == 0
assert 0 / inf == 0
assert isnan(inf / inf)
assert isnan(inf / -inf)
assert isnan(inf / nan)
assert mpf('inf') == mpf('+inf') == inf
assert mpf('-inf') == -inf
assert isnan(mpf('nan'))
assert isinf(inf)
assert isinf(-inf)
assert not isinf(mpf(0))
assert not isinf(nan)
def test_special_powers():
assert inf**3 == inf
assert isnan(inf**0)
assert inf**-3 == 0
assert (-inf)**2 == inf
assert (-inf)**3 == -inf
assert isnan((-inf)**0)
assert (-inf)**-2 == 0
assert (-inf)**-3 == 0
assert isnan(nan**5)
assert isnan(nan**0)
def test_functions_special():
assert exp(inf) == inf
assert exp(-inf) == 0
assert isnan(exp(nan))
assert log(inf) == inf
assert isnan(log(nan))
assert isnan(sin(inf))
assert isnan(sin(nan))
assert atan(inf).ae(pi/2)
assert atan(-inf).ae(-pi/2)
assert isnan(sqrt(nan))
assert sqrt(inf) == inf
def test_convert_special():
float_inf = 1e300 * 1e300
float_ninf = -float_inf
float_nan = float_inf/float_ninf
assert mpf(3) * float_inf == inf
assert mpf(3) * float_ninf == -inf
assert isnan(mpf(3) * float_nan)
assert not (mpf(3) < float_nan)
assert not (mpf(3) > float_nan)
assert not (mpf(3) <= float_nan)
assert not (mpf(3) >= float_nan)
assert float(mpf('1e1000')) == float_inf
assert float(mpf('-1e1000')) == float_ninf
assert float(mpf('1e100000000000000000')) == float_inf
assert float(mpf('-1e100000000000000000')) == float_ninf
assert float(mpf('1e-100000000000000000')) == 0.0
def test_div_bug():
assert isnan(nan/1)
assert isnan(nan/2)
assert inf/2 == inf
assert (-inf)/2 == -inf

View File

@ -0,0 +1,14 @@
from mpmath import nstr, matrix, inf
def test_nstr():
m = matrix([[0.75, 0.190940654, -0.0299195971],
[0.190940654, 0.65625, 0.205663228],
[-0.0299195971, 0.205663228, 0.64453125e-20]])
assert nstr(m, 4, min_fixed=-inf) == \
'''[ 0.75 0.1909 -0.02992]
[ 0.1909 0.6563 0.2057]
[-0.02992 0.2057 0.000000000000000000006445]'''
assert nstr(m, 4) == \
'''[ 0.75 0.1909 -0.02992]
[ 0.1909 0.6563 0.2057]
[-0.02992 0.2057 6.445e-21]'''

View File

@ -0,0 +1,53 @@
from mpmath import *
def test_sumem():
mp.dps = 15
assert sumem(lambda k: 1/k**2.5, [50, 100]).ae(0.0012524505324784962)
assert sumem(lambda k: k**4 + 3*k + 1, [10, 100]).ae(2050333103)
def test_nsum():
mp.dps = 15
assert nsum(lambda x: x**2, [1, 3]) == 14
assert nsum(lambda k: 1/factorial(k), [0, inf]).ae(e)
assert nsum(lambda k: (-1)**(k+1) / k, [1, inf]).ae(log(2))
assert nsum(lambda k: (-1)**(k+1) / k**2, [1, inf]).ae(pi**2 / 12)
assert nsum(lambda k: (-1)**k / log(k), [2, inf]).ae(0.9242998972229388)
assert nsum(lambda k: 1/k**2, [1, inf]).ae(pi**2 / 6)
assert nsum(lambda k: 2**k/fac(k), [0, inf]).ae(exp(2))
assert nsum(lambda k: 1/k**2, [4, inf], method='e').ae(0.2838229557371153)
assert abs(fp.nsum(lambda k: 1/k**4, [1, fp.inf]) - 1.082323233711138) < 1e-5
assert abs(fp.nsum(lambda k: 1/k**4, [1, fp.inf], method='e') - 1.082323233711138) < 1e-4
def test_nprod():
mp.dps = 15
assert nprod(lambda k: exp(1/k**2), [1,inf], method='r').ae(exp(pi**2/6))
assert nprod(lambda x: x**2, [1, 3]) == 36
def test_fsum():
mp.dps = 15
assert fsum([]) == 0
assert fsum([-4]) == -4
assert fsum([2,3]) == 5
assert fsum([1e-100,1]) == 1
assert fsum([1,1e-100]) == 1
assert fsum([1e100,1]) == 1e100
assert fsum([1,1e100]) == 1e100
assert fsum([1e-100,0]) == 1e-100
assert fsum([1e-100,1e100,1e-100]) == 1e100
assert fsum([2,1+1j,1]) == 4+1j
assert fsum([2,inf,3]) == inf
assert fsum([2,-1], absolute=1) == 3
assert fsum([2,-1], squared=1) == 5
assert fsum([1,1+j], squared=1) == 1+2j
assert fsum([1,3+4j], absolute=1) == 6
assert fsum([1,2+3j], absolute=1, squared=1) == 14
assert isnan(fsum([inf,-inf]))
assert fsum([inf,-inf], absolute=1) == inf
assert fsum([inf,-inf], squared=1) == inf
assert fsum([inf,-inf], absolute=1, squared=1) == inf
assert iv.fsum([1,mpi(2,3)]) == mpi(3,4)
def test_fprod():
mp.dps = 15
assert fprod([]) == 1
assert fprod([2,3]) == 6

View File

@ -0,0 +1,136 @@
from mpmath import *
from mpmath.libmp import *
def test_trig_misc_hard():
mp.prec = 53
# Worst-case input for an IEEE double, from a paper by Kahan
x = ldexp(6381956970095103,797)
assert cos(x) == mpf('-4.6871659242546277e-19')
assert sin(x) == 1
mp.prec = 150
a = mpf(10**50)
mp.prec = 53
assert sin(a).ae(-0.7896724934293100827)
assert cos(a).ae(-0.6135286082336635622)
# Check relative accuracy close to x = zero
assert sin(1e-100) == 1e-100 # when rounding to nearest
assert sin(1e-6).ae(9.999999999998333e-007, rel_eps=2e-15, abs_eps=0)
assert sin(1e-6j).ae(1.0000000000001666e-006j, rel_eps=2e-15, abs_eps=0)
assert sin(-1e-6j).ae(-1.0000000000001666e-006j, rel_eps=2e-15, abs_eps=0)
assert cos(1e-100) == 1
assert cos(1e-6).ae(0.9999999999995)
assert cos(-1e-6j).ae(1.0000000000005)
assert tan(1e-100) == 1e-100
assert tan(1e-6).ae(1.0000000000003335e-006, rel_eps=2e-15, abs_eps=0)
assert tan(1e-6j).ae(9.9999999999966644e-007j, rel_eps=2e-15, abs_eps=0)
assert tan(-1e-6j).ae(-9.9999999999966644e-007j, rel_eps=2e-15, abs_eps=0)
def test_trig_near_zero():
mp.dps = 15
for r in [round_nearest, round_down, round_up, round_floor, round_ceiling]:
assert sin(0, rounding=r) == 0
assert cos(0, rounding=r) == 1
a = mpf('1e-100')
b = mpf('-1e-100')
assert sin(a, rounding=round_nearest) == a
assert sin(a, rounding=round_down) < a
assert sin(a, rounding=round_floor) < a
assert sin(a, rounding=round_up) >= a
assert sin(a, rounding=round_ceiling) >= a
assert sin(b, rounding=round_nearest) == b
assert sin(b, rounding=round_down) > b
assert sin(b, rounding=round_floor) <= b
assert sin(b, rounding=round_up) <= b
assert sin(b, rounding=round_ceiling) > b
assert cos(a, rounding=round_nearest) == 1
assert cos(a, rounding=round_down) < 1
assert cos(a, rounding=round_floor) < 1
assert cos(a, rounding=round_up) == 1
assert cos(a, rounding=round_ceiling) == 1
assert cos(b, rounding=round_nearest) == 1
assert cos(b, rounding=round_down) < 1
assert cos(b, rounding=round_floor) < 1
assert cos(b, rounding=round_up) == 1
assert cos(b, rounding=round_ceiling) == 1
def test_trig_near_n_pi():
mp.dps = 15
a = [n*pi for n in [1, 2, 6, 11, 100, 1001, 10000, 100001]]
mp.dps = 135
a.append(10**100 * pi)
mp.dps = 15
assert sin(a[0]) == mpf('1.2246467991473531772e-16')
assert sin(a[1]) == mpf('-2.4492935982947063545e-16')
assert sin(a[2]) == mpf('-7.3478807948841190634e-16')
assert sin(a[3]) == mpf('4.8998251578625894243e-15')
assert sin(a[4]) == mpf('1.9643867237284719452e-15')
assert sin(a[5]) == mpf('-8.8632615209684813458e-15')
assert sin(a[6]) == mpf('-4.8568235395684898392e-13')
assert sin(a[7]) == mpf('3.9087342299491231029e-11')
assert sin(a[8]) == mpf('-1.369235466754566993528e-36')
r = round_nearest
assert cos(a[0], rounding=r) == -1
assert cos(a[1], rounding=r) == 1
assert cos(a[2], rounding=r) == 1
assert cos(a[3], rounding=r) == -1
assert cos(a[4], rounding=r) == 1
assert cos(a[5], rounding=r) == -1
assert cos(a[6], rounding=r) == 1
assert cos(a[7], rounding=r) == -1
assert cos(a[8], rounding=r) == 1
r = round_up
assert cos(a[0], rounding=r) == -1
assert cos(a[1], rounding=r) == 1
assert cos(a[2], rounding=r) == 1
assert cos(a[3], rounding=r) == -1
assert cos(a[4], rounding=r) == 1
assert cos(a[5], rounding=r) == -1
assert cos(a[6], rounding=r) == 1
assert cos(a[7], rounding=r) == -1
assert cos(a[8], rounding=r) == 1
r = round_down
assert cos(a[0], rounding=r) > -1
assert cos(a[1], rounding=r) < 1
assert cos(a[2], rounding=r) < 1
assert cos(a[3], rounding=r) > -1
assert cos(a[4], rounding=r) < 1
assert cos(a[5], rounding=r) > -1
assert cos(a[6], rounding=r) < 1
assert cos(a[7], rounding=r) > -1
assert cos(a[8], rounding=r) < 1
r = round_floor
assert cos(a[0], rounding=r) == -1
assert cos(a[1], rounding=r) < 1
assert cos(a[2], rounding=r) < 1
assert cos(a[3], rounding=r) == -1
assert cos(a[4], rounding=r) < 1
assert cos(a[5], rounding=r) == -1
assert cos(a[6], rounding=r) < 1
assert cos(a[7], rounding=r) == -1
assert cos(a[8], rounding=r) < 1
r = round_ceiling
assert cos(a[0], rounding=r) > -1
assert cos(a[1], rounding=r) == 1
assert cos(a[2], rounding=r) == 1
assert cos(a[3], rounding=r) > -1
assert cos(a[4], rounding=r) == 1
assert cos(a[5], rounding=r) > -1
assert cos(a[6], rounding=r) == 1
assert cos(a[7], rounding=r) > -1
assert cos(a[8], rounding=r) == 1
mp.dps = 15

View File

@ -0,0 +1,32 @@
"""
Limited tests of the visualization module. Right now it just makes
sure that passing custom Axes works.
"""
from mpmath import mp, fp
def test_axes():
try:
import matplotlib
version = matplotlib.__version__.split("-")[0]
version = version.split(".")[:2]
if [int(_) for _ in version] < [0,99]:
raise ImportError
import pylab
except ImportError:
print("\nSkipping test (pylab not available or too old version)\n")
return
fig = pylab.figure()
axes = fig.add_subplot(111)
for ctx in [mp, fp]:
ctx.plot(lambda x: x**2, [0, 3], axes=axes)
assert axes.get_xlabel() == 'x'
assert axes.get_ylabel() == 'f(x)'
fig = pylab.figure()
axes = fig.add_subplot(111)
for ctx in [mp, fp]:
ctx.cplot(lambda z: z, [-2, 2], [-10, 10], axes=axes)
assert axes.get_xlabel() == 'Re(z)'
assert axes.get_ylabel() == 'Im(z)'

View File

@ -0,0 +1,224 @@
"""
Torture tests for asymptotics and high precision evaluation of
special functions.
(Other torture tests may also be placed here.)
Running this file (gmpy recommended!) takes several CPU minutes.
With Python 2.6+, multiprocessing is used automatically to run tests
in parallel if many cores are available. (A single test may take between
a second and several minutes; possibly more.)
The idea:
* We evaluate functions at positive, negative, imaginary, 45- and 135-degree
complex values with magnitudes between 10^-20 to 10^20, at precisions between
5 and 150 digits (we can go even higher for fast functions).
* Comparing the result from two different precision levels provides
a strong consistency check (particularly for functions that use
different algorithms at different precision levels).
* That the computation finishes at all (without failure), within reasonable
time, provides a check that evaluation works at all: that the code runs,
that it doesn't get stuck in an infinite loop, and that it doesn't use
some extremely slowly algorithm where it could use a faster one.
TODO:
* Speed up those functions that take long to finish!
* Generalize to test more cases; more options.
* Implement a timeout mechanism.
* Some functions are notably absent, including the following:
* inverse trigonometric functions (some become inaccurate for complex arguments)
* ci, si (not implemented properly for large complex arguments)
* zeta functions (need to modify test not to try too large imaginary values)
* and others...
"""
import sys, os
from timeit import default_timer as clock
if "-nogmpy" in sys.argv:
sys.argv.remove('-nogmpy')
os.environ['MPMATH_NOGMPY'] = 'Y'
filt = ''
if not sys.argv[-1].endswith(".py"):
filt = sys.argv[-1]
from mpmath import *
from mpmath.libmp.backend import exec_
def test_asymp(f, maxdps=150, verbose=False, huge_range=False):
dps = [5,15,25,50,90,150,500,1500,5000,10000]
dps = [p for p in dps if p <= maxdps]
def check(x,y,p,inpt):
if abs(x-y)/abs(y) < workprec(20)(power)(10, -p+1):
return
print()
print("Error!")
print("Input:", inpt)
print("dps =", p)
print("Result 1:", x)
print("Result 2:", y)
print("Absolute error:", abs(x-y))
print("Relative error:", abs(x-y)/abs(y))
raise AssertionError
exponents = range(-20,20)
if huge_range:
exponents += [-1000, -100, -50, 50, 100, 1000]
for n in exponents:
if verbose:
sys.stdout.write(". ")
mp.dps = 25
xpos = mpf(10)**n / 1.1287
xneg = -xpos
ximag = xpos*j
xcomplex1 = xpos*(1+j)
xcomplex2 = xpos*(-1+j)
for i in range(len(dps)):
if verbose:
print("Testing dps = %s" % dps[i])
mp.dps = dps[i]
new = f(xpos), f(xneg), f(ximag), f(xcomplex1), f(xcomplex2)
if i != 0:
p = dps[i-1]
check(prev[0], new[0], p, xpos)
check(prev[1], new[1], p, xneg)
check(prev[2], new[2], p, ximag)
check(prev[3], new[3], p, xcomplex1)
check(prev[4], new[4], p, xcomplex2)
prev = new
if verbose:
print()
a1, a2, a3, a4, a5 = 1.5, -2.25, 3.125, 4, 2
def test_bernoulli_huge():
p, q = bernfrac(9000)
assert p % 10**10 == 9636701091
assert q == 4091851784687571609141381951327092757255270
mp.dps = 15
assert str(bernoulli(10**100)) == '-2.58183325604736e+987675256497386331227838638980680030172857347883537824464410652557820800494271520411283004120790908623'
mp.dps = 50
assert str(bernoulli(10**100)) == '-2.5818332560473632073252488656039475548106223822913e+987675256497386331227838638980680030172857347883537824464410652557820800494271520411283004120790908623'
mp.dps = 15
cases = """\
test_bernoulli_huge()
test_asymp(lambda z: +pi, maxdps=10000)
test_asymp(lambda z: +e, maxdps=10000)
test_asymp(lambda z: +ln2, maxdps=10000)
test_asymp(lambda z: +ln10, maxdps=10000)
test_asymp(lambda z: +phi, maxdps=10000)
test_asymp(lambda z: +catalan, maxdps=5000)
test_asymp(lambda z: +euler, maxdps=5000)
test_asymp(lambda z: +glaisher, maxdps=1000)
test_asymp(lambda z: +khinchin, maxdps=1000)
test_asymp(lambda z: +twinprime, maxdps=150)
test_asymp(lambda z: stieltjes(2), maxdps=150)
test_asymp(lambda z: +mertens, maxdps=150)
test_asymp(lambda z: +apery, maxdps=5000)
test_asymp(sqrt, maxdps=10000, huge_range=True)
test_asymp(cbrt, maxdps=5000, huge_range=True)
test_asymp(lambda z: root(z,4), maxdps=5000, huge_range=True)
test_asymp(lambda z: root(z,-5), maxdps=5000, huge_range=True)
test_asymp(exp, maxdps=5000, huge_range=True)
test_asymp(expm1, maxdps=1500)
test_asymp(ln, maxdps=5000, huge_range=True)
test_asymp(cosh, maxdps=5000)
test_asymp(sinh, maxdps=5000)
test_asymp(tanh, maxdps=1500)
test_asymp(sin, maxdps=5000, huge_range=True)
test_asymp(cos, maxdps=5000, huge_range=True)
test_asymp(tan, maxdps=1500)
test_asymp(agm, maxdps=1500, huge_range=True)
test_asymp(ellipk, maxdps=1500)
test_asymp(ellipe, maxdps=1500)
test_asymp(lambertw, huge_range=True)
test_asymp(lambda z: lambertw(z,-1))
test_asymp(lambda z: lambertw(z,1))
test_asymp(lambda z: lambertw(z,4))
test_asymp(gamma)
test_asymp(loggamma) # huge_range=True ?
test_asymp(ei)
test_asymp(e1)
test_asymp(li, huge_range=True)
test_asymp(ci)
test_asymp(si)
test_asymp(chi)
test_asymp(shi)
test_asymp(erf)
test_asymp(erfc)
test_asymp(erfi)
test_asymp(lambda z: besselj(2, z))
test_asymp(lambda z: bessely(2, z))
test_asymp(lambda z: besseli(2, z))
test_asymp(lambda z: besselk(2, z))
test_asymp(lambda z: besselj(-2.25, z))
test_asymp(lambda z: bessely(-2.25, z))
test_asymp(lambda z: besseli(-2.25, z))
test_asymp(lambda z: besselk(-2.25, z))
test_asymp(airyai)
test_asymp(airybi)
test_asymp(lambda z: hyp0f1(a1, z))
test_asymp(lambda z: hyp1f1(a1, a2, z))
test_asymp(lambda z: hyp1f2(a1, a2, a3, z))
test_asymp(lambda z: hyp2f0(a1, a2, z))
test_asymp(lambda z: hyperu(a1, a2, z))
test_asymp(lambda z: hyp2f1(a1, a2, a3, z))
test_asymp(lambda z: hyp2f2(a1, a2, a3, a4, z))
test_asymp(lambda z: hyp2f3(a1, a2, a3, a4, a5, z))
test_asymp(lambda z: coulombf(a1, a2, z))
test_asymp(lambda z: coulombg(a1, a2, z))
test_asymp(lambda z: polylog(2,z))
test_asymp(lambda z: polylog(3,z))
test_asymp(lambda z: polylog(-2,z))
test_asymp(lambda z: expint(4, z))
test_asymp(lambda z: expint(-4, z))
test_asymp(lambda z: expint(2.25, z))
test_asymp(lambda z: gammainc(2.5, z, 5))
test_asymp(lambda z: gammainc(2.5, 5, z))
test_asymp(lambda z: hermite(3, z))
test_asymp(lambda z: hermite(2.5, z))
test_asymp(lambda z: legendre(3, z))
test_asymp(lambda z: legendre(4, z))
test_asymp(lambda z: legendre(2.5, z))
test_asymp(lambda z: legenp(a1, a2, z))
test_asymp(lambda z: legenq(a1, a2, z), maxdps=90) # abnormally slow
test_asymp(lambda z: jtheta(1, z, 0.5))
test_asymp(lambda z: jtheta(2, z, 0.5))
test_asymp(lambda z: jtheta(3, z, 0.5))
test_asymp(lambda z: jtheta(4, z, 0.5))
test_asymp(lambda z: jtheta(1, z, 0.5, 1))
test_asymp(lambda z: jtheta(2, z, 0.5, 1))
test_asymp(lambda z: jtheta(3, z, 0.5, 1))
test_asymp(lambda z: jtheta(4, z, 0.5, 1))
test_asymp(barnesg, maxdps=90)
"""
def testit(line):
if filt in line:
print(line)
t1 = clock()
exec_(line, globals(), locals())
t2 = clock()
elapsed = t2-t1
print("Time:", elapsed, "for", line, "(OK)")
if __name__ == '__main__':
try:
from multiprocessing import Pool
mapf = Pool(None).map
print("Running tests with multiprocessing")
except ImportError:
print("Not using multiprocessing")
mapf = map
t1 = clock()
tasks = cases.splitlines()
mapf(testit, tasks)
t2 = clock()
print("Cumulative wall time:", t2-t1)