switching to high quality piper tts and added label translations
This commit is contained in:
@@ -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)
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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')
|
||||
@@ -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)
|
||||
@@ -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) )
|
||||
@@ -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
@@ -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
@@ -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')
|
||||
@@ -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
|
||||
@@ -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)'
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)]])
|
||||
@@ -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)
|
||||
@@ -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))
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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]'''
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)'
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user