import cmath import math import random import pytest from mpmath import (acos, acosh, acot, acoth, acsc, acsch, arange, arg, asec, asech, asin, asinh, atan, atan2, atanh, catalan, cbrt, ceil, conj, cos, cos_sin, cosh, cospi, cospi_sinpi, cot, coth, csc, csch, cyclotomic, degree, degrees, e, eps, euler, exp, exp2, expj, expjpi, expm1, fabs, fadd, fib, fibonacci, floor, fmod, fp, frexp, glaisher, hypot, im, inf, isnan, j, khinchin, ldexp, linspace, ln, ln2, ln10, log, log1p, log2, log10, mertens, mp, mpc, mpf, nan, nthroot, phi, pi, power, powm1, radians, rand, re, root, sec, sech, sign, sin, sinc, sincpi, sinh, sinpi, sqrt, tan, tanh, twinprime, unitroots) from mpmath.libmp import (MPZ, ComplexResult, from_int, mpf_gt, mpf_lt, mpf_mul, mpf_pow_int, mpf_sqrt, round_ceiling, round_down, round_nearest, round_up) from mpmath.libmp.libmpf import mpf_rand 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(): # 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)) mp2 = mp.clone() mp2.trap_complex = True pytest.raises(ComplexResult, lambda: mp2.sqrt(-1)) pytest.raises(ComplexResult, lambda: mp2.mpf(-1)**0.5) pytest.raises(ComplexResult, lambda: mp2.mpf(-1)**mp2.mpf(0.5)) def test_sqrt_special(): assert sqrt(mpc(+inf, +inf)) == mpc(inf, +inf) assert sqrt(mpc(-inf, +inf)) == mpc(inf, +inf) assert sqrt(mpc( nan, +inf)) == mpc(inf, +inf) assert sqrt(mpc(+inf, -inf)) == mpc(inf, -inf) assert sqrt(mpc(-inf, -inf)) == mpc(inf, -inf) assert sqrt(mpc( nan, -inf)) == mpc(inf, -inf) 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) # issue 1011 assert hypot(1.0000044432326138, 1.0068578402095993) == mpf('1.4190742041473763') 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 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, MPZ(8198646019315405), -53, 53))) assert a.bc == a.man.bit_length() mp.prec = 67 a = exp(mpf((1, MPZ(1781864658064754565), -60, 61))) assert a.bc == a.man.bit_length() 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(): 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) # Taylor series assert log(0.99999).ae(-1.0000050000287824e-5) assert log(1.00001).ae(9.9999500003988414e-6) # 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) # issue 774 assert log(mpc(+inf, +inf)) == log1p(mpc(+inf, +inf)) == mpc(inf, +pi/4) assert log(mpc(+inf, -inf)) == log1p(mpc(+inf, -inf)) == mpc(inf, -pi/4) assert log(mpc(-inf, +inf)) == log1p(mpc(-inf, +inf)) == mpc(inf, +3*pi/4) assert log(mpc(-inf, -inf)) == log1p(mpc(-inf, -inf)) == mpc(inf, -3*pi/4) 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) 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)]) def test_asin(): pi4 = pi/4 assert asin(mpc(+inf, +inf)) == mpc(+pi4, +inf) assert asin(mpc(+inf, -inf)) == mpc(+pi4, -inf) assert asin(mpc(-inf, +inf)) == mpc(-pi4, +inf) assert asin(mpc(-inf, -inf)) == mpc(-pi4, -inf) r = asin(mpc(+inf, nan)) assert isnan(r.real) and r.imag == -inf r = asin(mpc(-inf, nan)) assert isnan(r.real) and r.imag == -inf r = asin(mpc(nan, +inf)) assert isnan(r.real) and r.imag == +inf r = asin(mpc(nan, -inf)) assert isnan(r.real) and r.imag == -inf pi2 = pi/2 assert asin(mpc(+inf, +1)) == mpc(pi2, +inf) assert asin(mpc(+inf, -1)) == mpc(pi2, -inf) assert asin(mpc(+inf, 0)) == mpc(pi2, -inf) assert asin(mpc(-inf, +1)) == mpc(-pi2, +inf) assert asin(mpc(-inf, -1)) == mpc(-pi2, -inf) assert asin(mpc(-inf, 0)) == mpc(-pi2, inf) assert asin(mpc(-2, 0)).ae(mpc(-pi2, -log(2 - sqrt(3)))) assert asin(mpc(+2, 0)).ae(mpc(+pi2, -log(2 + sqrt(3)))) assert asin(mpc(0.5, 0)).ae(pi/6) # issue 787 assert asin(mpc(0, 1e-22)).ae(1e-22j) mp.prec = 700 assert asin(mpc(0, 1e-220)).ae(1e-220j) mp.prec = 53 def test_acos(): pi4 = pi/4 assert acos(mpc(+inf, +inf)) == mpc(+pi4, -inf) assert acos(mpc(+inf, -inf)) == mpc(+pi4, +inf) assert acos(mpc(-inf, +inf)) == mpc(pi4*3, -inf) assert acos(mpc(-inf, -inf)) == mpc(pi4*3, +inf) r = acos(mpc(+inf, nan)) assert isnan(r.real) and r.imag == inf r = acos(mpc(-inf, nan)) assert isnan(r.real) and r.imag == inf r = acos(mpc(nan, +inf)) assert isnan(r.real) and r.imag == -inf r = acos(mpc(nan, -inf)) assert isnan(r.real) and r.imag == +inf pi2 = pi/2 assert acos(mpc(+inf, +1)) == mpc(0.0, -inf) assert acos(mpc(+inf, -1)) == mpc(0.0, +inf) assert acos(mpc(+inf, 0)) == mpc(0.0, +inf) assert acos(mpc(-inf, +1)) == mpc(pi, -inf) assert acos(mpc(-inf, -1)) == mpc(pi, +inf) assert acos(mpc(-inf, 0)) == mpc(pi, -inf) assert acos(mpc(+1, +inf)) == mpc(pi2, -inf) assert acos(mpc(-1, +inf)) == mpc(pi2, -inf) assert acos(mpc(0, +inf)) == mpc(pi2, -inf) assert acos(mpc(+1, -inf)) == mpc(pi2, +inf) assert acos(mpc(-1, -inf)) == mpc(pi2, +inf) assert acos(mpc(0, -inf)) == mpc(pi2, +inf) assert acos(mpc(-2, 0)).ae(mpc(pi, log(2 - sqrt(3)))) assert acos(mpc(+2, 0)).ae(mpc(0, log(2 + sqrt(3)))) assert acos(mpc(0.5, 0)).ae(pi/3) def test_atan(): 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(): 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 atan2(inf,inf).ae(pi/4) assert atan2(-inf,inf).ae(-pi/4) assert atan2(inf,-inf).ae(3*pi/4) assert atan2(-inf,-inf).ae(-3*pi/4) 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) def test_invhyperb_inaccuracy(): 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(): 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 acot(cmath.infj) == 0 assert acot(cmath.inf) == 0 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(): 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(): 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) assert frexp(inf) == (inf, 0) assert frexp(-inf) == (-inf, 0) r = frexp(nan) assert isnan(r[0]) and r[1] == 0 def test_aliases(): assert ln(7) == log(7) assert log10(3.75) == log(3.75,10) assert log2(1.25) == log(1.25,2) assert exp2(-0.5) == power(2, -0.5) 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) 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) 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) # tests for nthroot rounding for rnd in ['n', 'u', 'd']: 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.rounding = 'n' 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 nthroot(j, 22).ae(cos(pi/44) + sin(pi/44)*1j) 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)) def test_mpcfun_real_imag(): 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') assert expjpi(cmath.infj) == 0 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(): 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(): assert abs(exp(1, dps=30)-e(dps=35)) < 1e-29 def test_tanh(): assert tanh(0) == 0 assert tanh(inf) == 1 assert tanh(-inf) == -1 assert isnan(tanh(nan)) assert tanh(mpc('inf', '0')) == 1 assert tanh(mpc(+inf, +inf)) == mpc(+1, 0) assert tanh(mpc(+inf, -inf)) == mpc(+1, 0) assert tanh(mpc(-inf, +inf)) == mpc(-1, 0) assert tanh(mpc(-inf, -inf)) == mpc(-1, 0) assert tanh(mpc(+inf, 2)) == mpc(+1, 0) assert tanh(mpc(-inf, 2)) == mpc(-1, 0) r = tanh(mpc(0, -inf)) assert r.real == 0 and isnan(r.imag) r = tanh(mpc(2, -inf)) assert isnan(r.real) and isnan(r.imag) assert tanh(mpc(+inf, nan)) == mpc(+1, 0) assert tanh(mpc(-inf, nan)) == mpc(-1, 0) def test_tan(): assert tan(mpc(+inf, +inf)) == mpc(0, +1) assert tan(mpc(+inf, -inf)) == mpc(0, -1) assert tan(mpc(-inf, +inf)) == mpc(0, +1) assert tan(mpc(-inf, -inf)) == mpc(0, -1) assert tan(mpc(2, +inf)) == mpc(0, +1) assert tan(mpc(2, -inf)) == mpc(0, -1) r = tan(mpc(-inf, 0)) assert isnan(r.real) and r.imag == 0 r = tan(mpc(-inf, 2)) assert isnan(r.real) and isnan(r.imag) assert tan(mpc(nan, +inf)) == mpc(0, +1) assert tan(mpc(nan, -inf)) == mpc(0, -1) def test_atanh(): 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(): 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(): 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) # issue 790 assert log1p(1.8370676479640493e-39-4.6885882517313053e-20j).ae(2.93621063767769e-39-4.6885882517313053e-20j, 0) assert log1p(-2.0476815825463086e-80-2.0235857941734692e-40j).ae(-2.3184935597344513e-84-2.0235857941734692e-40j, 0) assert log1p(-6.4922176418510124e-21+1.1394926627101214e-10j).ae(-1.4201199664289643e-37+1.1394926627101214e-10j, 0) assert log1p(-1.430796815051627e-72+1.691624553529315e-36j).ae(4.6709293580298264e-91+1.691624553529315e-36j, 0) assert log1p(-3.1061140011623543e-21+7.881768838480807e-11j).ae(4.3173401185459216e-38+7.881768838480807e-11j, 0) assert log1p(-1.999999873062092e-40+1.999999936531045e-20j).ae(1.9999997461241924e-80+1.999999936531045e-20j) # issue 853 mp.dps = 25 r = log1p(6e-30) assert type(r) is type(r.real) r = mp.log1p(7e-30) assert type(r) is type(r.real) r = mp.log1p(0.1 + 0j) assert type(r) is not type(r.real) r = mp.log1p(1e-30 + 0j) assert type(r) is not type(r.real) def test_powm1(): 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(): 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 def test_mp_nan_in_args(): assert mp.isnan(mp.legendre(1.2, mp.nan)) # issue 485 assert mp.isnan(mp.hyp2f1(0.5, 0.5, 0.5, mp.nan)) assert mp.isnan(mp.hyp2f1(0.5, 2.2, 0.5, mp.nan)) assert mp.isnan(mp.hyp2f1(0.4, 2.2, 0.5, mp.nan)) # issue 479 assert mp.isnan(mp.chebyt(2.3, mp.nan)) # issue 478 assert mp.isnan(mp.chebyt(13, mp.nan)) assert mp.isnan(mp.chebyt(17, mp.nan)) assert mp.isnan(mp.hyp1f1(0, 1, mp.nan)) # issue 507 assert mp.isnan(mp.hyp1f1(1, 1, mp.nan)) assert mp.isnan(mp.hyp1f1(1, 1.1, mp.nan)) assert mp.isnan(mp.hyp1f1(1, 2, mp.nan)) assert mp.isnan(mp.hyp1f1(1, 3, mp.nan)) assert mp.isnan(mp.hyp1f1(1, 4, mp.nan)) assert mp.isnan(mp.hyp1f1(2, 1, mp.nan)) assert mp.isnan(mp.hyp1f1(2, 2, mp.nan)) assert mp.isnan(mp.hyp1f1(0, 2, mp.nan)) assert mp.isnan(mp.hyp1f1(0, 4, mp.nan)) assert mp.isnan(mp.hyp0f1(2.5, mp.nan)) # issue 489 assert mp.isnan(mp.hyp0f1(25, mp.nan)) assert mp.isnan(mp.hyp0f1(2513, mp.nan)) assert mp.isnan(mp.hyp0f1(.25, mp.nan)) assert mp.isnan(mp.hyp1f1(2.5,2.2, mp.nan)) # issue 488 assert mp.isnan(mp.hyp1f1(1,2.2, mp.nan)) assert mp.isnan(mp.hyp1f1(1,2002.2, mp.nan)) assert mp.isnan(mp.hyp2f2(0.4, 2.5, 2.2, 0.7, mp.nan)) # issue 509 assert mp.isnan(mp.gegenbauer(0, 2.5, mp.nan)) # issue 508 assert mp.isnan(mp.gegenbauer(1, 2.5, mp.nan)) assert mp.isnan(mp.gegenbauer(2, 2.5, mp.nan)) assert mp.isnan(mp.gegenbauer(2, 5, mp.nan)) assert mp.isnan(mp.laguerre(0, 2.5, mp.nan)) # issue 506 assert mp.isnan(mp.laguerre(1, 2.5, mp.nan)) assert mp.isnan(mp.laguerre(1, 2.5345, mp.nan)) assert mp.isnan(mp.laguerre(2, 2, mp.nan)) assert mp.isnan(mp.laguerre(2, 5, mp.nan)) def test_issue_749(): assert mp.asinh(mp.inf) == mp.inf assert mp.asinh(mp.mpc(mp.inf, 0)) == mp.mpc(mp.inf, 0) assert fp.asinh(fp.mpc(fp.inf, 0)) == fp.mpc(fp.inf, 0) def test_issue_1035(): assert mp.acos(1e-50j).ae(1.5707963267948966) def test_wrap_libmp_api(): assert sin(1) != sin(1, prec=1000) assert sin(1) != sin(1, dps=100) assert sin(1, rounding='d') < sin(1, rounding='u') pytest.raises(ValueError, lambda: sin(1, prec=123, dps=321)) pytest.raises(TypeError, lambda: sin(1, 2))