>> giant_steps(50,1000)
+ [66, 128, 253, 502, 1000]
+ >>> giant_steps(50,1000,4)
+ [65, 252, 1000]
+
+ """
+ L = [target]
+ while L[-1] > start*n:
+ L = L + [L[-1]//n + 2]
+ return L[::-1]
+
+def rshift(x, n):
+ """For an integer x, calculate x >> n with the fastest (floor)
+ rounding. Unlike the plain Python expression (x >> n), n is
+ allowed to be negative, in which case a left shift is performed."""
+ if n >= 0: return x >> n
+ else: return x << (-n)
+
+def lshift(x, n):
+ """For an integer x, calculate x << n. Unlike the plain Python
+ expression (x << n), n is allowed to be negative, in which case a
+ right shift with default (floor) rounding is performed."""
+ if n >= 0: return x << n
+ else: return x >> (-n)
+
+if BACKEND == 'sage':
+ import operator
+ rshift = operator.rshift
+ lshift = operator.lshift
+
+def python_trailing(n):
+ """Count the number of trailing zero bits in abs(n)."""
+ if not n:
+ return 0
+ low_byte = n & 0xff
+ if low_byte:
+ return small_trailing[low_byte]
+ t = 8
+ n >>= 8
+ while not n & 0xff:
+ n >>= 8
+ t += 8
+ return t + small_trailing[n & 0xff]
+
+if BACKEND == 'gmpy':
+ if gmpy.version() >= '2':
+ def gmpy_trailing(n):
+ """Count the number of trailing zero bits in abs(n) using gmpy."""
+ if n: return MPZ(n).bit_scan1()
+ else: return 0
+ else:
+ def gmpy_trailing(n):
+ """Count the number of trailing zero bits in abs(n) using gmpy."""
+ if n: return MPZ(n).scan1()
+ else: return 0
+
+# Small powers of 2
+powers = [1<<_ for _ in range(300)]
+
+def python_bitcount(n):
+ """Calculate bit size of the nonnegative integer n."""
+ bc = bisect(powers, n)
+ if bc != 300:
+ return bc
+ bc = int(math.log(n, 2)) - 4
+ return bc + bctable[n>>bc]
+
+def gmpy_bitcount(n):
+ """Calculate bit size of the nonnegative integer n."""
+ if n: return MPZ(n).numdigits(2)
+ else: return 0
+
+#def sage_bitcount(n):
+# if n: return MPZ(n).nbits()
+# else: return 0
+
+def sage_trailing(n):
+ return MPZ(n).trailing_zero_bits()
+
+if BACKEND == 'gmpy':
+ bitcount = gmpy_bitcount
+ trailing = gmpy_trailing
+elif BACKEND == 'sage':
+ sage_bitcount = sage_utils.bitcount
+ bitcount = sage_bitcount
+ trailing = sage_trailing
+else:
+ bitcount = python_bitcount
+ trailing = python_trailing
+
+if BACKEND == 'gmpy' and 'bit_length' in dir(gmpy):
+ bitcount = gmpy.bit_length
+
+# Used to avoid slow function calls as far as possible
+trailtable = [trailing(n) for n in range(256)]
+bctable = [bitcount(n) for n in range(1024)]
+
+# TODO: speed up for bases 2, 4, 8, 16, ...
+
+def bin_to_radix(x, xbits, base, bdigits):
+ """Changes radix of a fixed-point number; i.e., converts
+ x * 2**xbits to floor(x * 10**bdigits)."""
+ return x * (MPZ(base)**bdigits) >> xbits
+
+stddigits = '0123456789abcdefghijklmnopqrstuvwxyz'
+
+def small_numeral(n, base=10, digits=stddigits):
+ """Return the string numeral of a positive integer in an arbitrary
+ base. Most efficient for small input."""
+ if base == 10:
+ return str(n)
+ digs = []
+ while n:
+ n, digit = divmod(n, base)
+ digs.append(digits[digit])
+ return "".join(digs[::-1])
+
+def numeral_python(n, base=10, size=0, digits=stddigits):
+ """Represent the integer n as a string of digits in the given base.
+ Recursive division is used to make this function about 3x faster
+ than Python's str() for converting integers to decimal strings.
+
+ The 'size' parameters specifies the number of digits in n; this
+ number is only used to determine splitting points and need not be
+ exact."""
+ if n <= 0:
+ if not n:
+ return "0"
+ return "-" + numeral(-n, base, size, digits)
+ # Fast enough to do directly
+ if size < 250:
+ return small_numeral(n, base, digits)
+ # Divide in half
+ half = (size // 2) + (size & 1)
+ A, B = divmod(n, base**half)
+ ad = numeral(A, base, half, digits)
+ bd = numeral(B, base, half, digits).rjust(half, "0")
+ return ad + bd
+
+def numeral_gmpy(n, base=10, size=0, digits=stddigits):
+ """Represent the integer n as a string of digits in the given base.
+ Recursive division is used to make this function about 3x faster
+ than Python's str() for converting integers to decimal strings.
+
+ The 'size' parameters specifies the number of digits in n; this
+ number is only used to determine splitting points and need not be
+ exact."""
+ if n < 0:
+ return "-" + numeral(-n, base, size, digits)
+ # gmpy.digits() may cause a segmentation fault when trying to convert
+ # extremely large values to a string. The size limit may need to be
+ # adjusted on some platforms, but 1500000 works on Windows and Linux.
+ if size < 1500000:
+ return gmpy.digits(n, base)
+ # Divide in half
+ half = (size // 2) + (size & 1)
+ A, B = divmod(n, MPZ(base)**half)
+ ad = numeral(A, base, half, digits)
+ bd = numeral(B, base, half, digits).rjust(half, "0")
+ return ad + bd
+
+if BACKEND == "gmpy":
+ numeral = numeral_gmpy
+else:
+ numeral = numeral_python
+
+_1_800 = 1<<800
+_1_600 = 1<<600
+_1_400 = 1<<400
+_1_200 = 1<<200
+_1_100 = 1<<100
+_1_50 = 1<<50
+
+def isqrt_small_python(x):
+ """
+ Correctly (floor) rounded integer square root, using
+ division. Fast up to ~200 digits.
+ """
+ if not x:
+ return x
+ if x < _1_800:
+ # Exact with IEEE double precision arithmetic
+ if x < _1_50:
+ return int(x**0.5)
+ # Initial estimate can be any integer >= the true root; round up
+ r = int(x**0.5 * 1.00000000000001) + 1
+ else:
+ bc = bitcount(x)
+ n = bc//2
+ r = int((x>>(2*n-100))**0.5+2)<<(n-50) # +2 is to round up
+ # The following iteration now precisely computes floor(sqrt(x))
+ # See e.g. Crandall & Pomerance, "Prime Numbers: A Computational
+ # Perspective"
+ while 1:
+ y = (r+x//r)>>1
+ if y >= r:
+ return r
+ r = y
+
+def isqrt_fast_python(x):
+ """
+ Fast approximate integer square root, computed using division-free
+ Newton iteration for large x. For random integers the result is almost
+ always correct (floor(sqrt(x))), but is 1 ulp too small with a roughly
+ 0.1% probability. If x is very close to an exact square, the answer is
+ 1 ulp wrong with high probability.
+
+ With 0 guard bits, the largest error over a set of 10^5 random
+ inputs of size 1-10^5 bits was 3 ulp. The use of 10 guard bits
+ almost certainly guarantees a max 1 ulp error.
+ """
+ # Use direct division-based iteration if sqrt(x) < 2^400
+ # Assume floating-point square root accurate to within 1 ulp, then:
+ # 0 Newton iterations good to 52 bits
+ # 1 Newton iterations good to 104 bits
+ # 2 Newton iterations good to 208 bits
+ # 3 Newton iterations good to 416 bits
+ if x < _1_800:
+ y = int(x**0.5)
+ if x >= _1_100:
+ y = (y + x//y) >> 1
+ if x >= _1_200:
+ y = (y + x//y) >> 1
+ if x >= _1_400:
+ y = (y + x//y) >> 1
+ return y
+ bc = bitcount(x)
+ guard_bits = 10
+ x <<= 2*guard_bits
+ bc += 2*guard_bits
+ bc += (bc&1)
+ hbc = bc//2
+ startprec = min(50, hbc)
+ # Newton iteration for 1/sqrt(x), with floating-point starting value
+ r = int(2.0**(2*startprec) * (x >> (bc-2*startprec)) ** -0.5)
+ pp = startprec
+ for p in giant_steps(startprec, hbc):
+ # r**2, scaled from real size 2**(-bc) to 2**p
+ r2 = (r*r) >> (2*pp - p)
+ # x*r**2, scaled from real size ~1.0 to 2**p
+ xr2 = ((x >> (bc-p)) * r2) >> p
+ # New value of r, scaled from real size 2**(-bc/2) to 2**p
+ r = (r * ((3<> (pp+1)
+ pp = p
+ # (1/sqrt(x))*x = sqrt(x)
+ return (r*(x>>hbc)) >> (p+guard_bits)
+
+def sqrtrem_python(x):
+ """Correctly rounded integer (floor) square root with remainder."""
+ # to check cutoff:
+ # plot(lambda x: timing(isqrt, 2**int(x)), [0,2000])
+ if x < _1_600:
+ y = isqrt_small_python(x)
+ return y, x - y*y
+ y = isqrt_fast_python(x) + 1
+ rem = x - y*y
+ # Correct remainder
+ while rem < 0:
+ y -= 1
+ rem += (1+2*y)
+ else:
+ if rem:
+ while rem > 2*(1+y):
+ y += 1
+ rem -= (1+2*y)
+ return y, rem
+
+def isqrt_python(x):
+ """Integer square root with correct (floor) rounding."""
+ return sqrtrem_python(x)[0]
+
+def sqrt_fixed(x, prec):
+ return isqrt_fast(x<= '2':
+ isqrt_small = isqrt_fast = isqrt = gmpy.isqrt
+ sqrtrem = gmpy.isqrt_rem
+ else:
+ isqrt_small = isqrt_fast = isqrt = gmpy.sqrt
+ sqrtrem = gmpy.sqrtrem
+elif BACKEND == 'sage':
+ isqrt_small = isqrt_fast = isqrt = \
+ getattr(sage_utils, "isqrt", lambda n: MPZ(n).isqrt())
+ sqrtrem = lambda n: MPZ(n).sqrtrem()
+else:
+ isqrt_small = isqrt_small_python
+ isqrt_fast = isqrt_fast_python
+ isqrt = isqrt_python
+ sqrtrem = sqrtrem_python
+
+
+def ifib(n, _cache={}):
+ """Computes the nth Fibonacci number as an integer, for
+ integer n."""
+ if n < 0:
+ return (-1)**(-n+1) * ifib(-n)
+ if n in _cache:
+ return _cache[n]
+ m = n
+ # Use Dijkstra's logarithmic algorithm
+ # The following implementation is basically equivalent to
+ # http://en.literateprograms.org/Fibonacci_numbers_(Scheme)
+ a, b, p, q = MPZ_ONE, MPZ_ZERO, MPZ_ZERO, MPZ_ONE
+ while n:
+ if n & 1:
+ aq = a*q
+ a, b = b*q+aq+a*p, b*p+aq
+ n -= 1
+ else:
+ qq = q*q
+ p, q = p*p+qq, qq+2*p*q
+ n >>= 1
+ if m < 250:
+ _cache[m] = b
+ return b
+
+MAX_FACTORIAL_CACHE = 1000
+
+def ifac(n, memo={0:1, 1:1}):
+ """Return n factorial (for integers n >= 0 only)."""
+ f = memo.get(n)
+ if f:
+ return f
+ k = len(memo)
+ p = memo[k-1]
+ MAX = MAX_FACTORIAL_CACHE
+ while k <= n:
+ p *= k
+ if k <= MAX:
+ memo[k] = p
+ k += 1
+ return p
+
+def ifac2(n, memo_pair=[{0:1}, {1:1}]):
+ """Return n!! (double factorial), integers n >= 0 only."""
+ memo = memo_pair[n&1]
+ f = memo.get(n)
+ if f:
+ return f
+ k = max(memo)
+ p = memo[k]
+ MAX = MAX_FACTORIAL_CACHE
+ while k < n:
+ k += 2
+ p *= k
+ if k <= MAX:
+ memo[k] = p
+ return p
+
+if BACKEND == 'gmpy':
+ ifac = gmpy.fac
+elif BACKEND == 'sage':
+ ifac = lambda n: int(sage.factorial(n))
+ ifib = sage.fibonacci
+
+def list_primes(n):
+ n = n + 1
+ sieve = list(xrange(n))
+ sieve[:2] = [0, 0]
+ for i in xrange(2, int(n**0.5)+1):
+ if sieve[i]:
+ for j in xrange(i**2, n, i):
+ sieve[j] = 0
+ return [p for p in sieve if p]
+
+if BACKEND == 'sage':
+ # Note: it is *VERY* important for performance that we convert
+ # the list to Python ints.
+ def list_primes(n):
+ return [int(_) for _ in sage.primes(n+1)]
+
+small_odd_primes = (3,5,7,11,13,17,19,23,29,31,37,41,43,47)
+small_odd_primes_set = set(small_odd_primes)
+
+def isprime(n):
+ """
+ Determines whether n is a prime number. A probabilistic test is
+ performed if n is very large. No special trick is used for detecting
+ perfect powers.
+
+ >>> sum(list_primes(100000))
+ 454396537
+ >>> sum(n*isprime(n) for n in range(100000))
+ 454396537
+
+ """
+ n = int(n)
+ if not n & 1:
+ return n == 2
+ if n < 50:
+ return n in small_odd_primes_set
+ for p in small_odd_primes:
+ if not n % p:
+ return False
+ m = n-1
+ s = trailing(m)
+ d = m >> s
+ def test(a):
+ x = pow(a,d,n)
+ if x == 1 or x == m:
+ return True
+ for r in xrange(1,s):
+ x = x**2 % n
+ if x == m:
+ return True
+ return False
+ # See http://primes.utm.edu/prove/prove2_3.html
+ if n < 1373653:
+ witnesses = [2,3]
+ elif n < 341550071728321:
+ witnesses = [2,3,5,7,11,13,17]
+ else:
+ witnesses = small_odd_primes
+ for a in witnesses:
+ if not test(a):
+ return False
+ return True
+
+def moebius(n):
+ """
+ Evaluates the Moebius function which is `mu(n) = (-1)^k` if `n`
+ is a product of `k` distinct primes and `mu(n) = 0` otherwise.
+
+ TODO: speed up using factorization
+ """
+ n = abs(int(n))
+ if n < 2:
+ return n
+ factors = []
+ for p in xrange(2, n+1):
+ if not (n % p):
+ if not (n % p**2):
+ return 0
+ if not sum(p % f for f in factors):
+ factors.append(p)
+ return (-1)**len(factors)
+
+def gcd(*args):
+ a = 0
+ for b in args:
+ if a:
+ while b:
+ a, b = b, a % b
+ else:
+ a = b
+ return a
+
+
+# Comment by Juan Arias de Reyna:
+#
+# I learn this method to compute EulerE[2n] from van de Lune.
+#
+# We apply the formula EulerE[2n] = (-1)^n 2**(-2n) sum_{j=0}^n a(2n,2j+1)
+#
+# where the numbers a(n,j) vanish for j > n+1 or j <= -1 and satisfies
+#
+# a(0,-1) = a(0,0) = 0; a(0,1)= 1; a(0,2) = a(0,3) = 0
+#
+# a(n,j) = a(n-1,j) when n+j is even
+# a(n,j) = (j-1) a(n-1,j-1) + (j+1) a(n-1,j+1) when n+j is odd
+#
+#
+# But we can use only one array unidimensional a(j) since to compute
+# a(n,j) we only need to know a(n-1,k) where k and j are of different parity
+# and we have not to conserve the used values.
+#
+# We cached up the values of Euler numbers to sufficiently high order.
+#
+# Important Observation: If we pretend to use the numbers
+# EulerE[1], EulerE[2], ... , EulerE[n]
+# it is convenient to compute first EulerE[n], since the algorithm
+# computes first all
+# the previous ones, and keeps them in the CACHE
+
+MAX_EULER_CACHE = 500
+
+def eulernum(m, _cache={0:MPZ_ONE}):
+ r"""
+ Computes the Euler numbers `E(n)`, which can be defined as
+ coefficients of the Taylor expansion of `1/cosh x`:
+
+ .. math ::
+
+ \frac{1}{\cosh x} = \sum_{n=0}^\infty \frac{E_n}{n!} x^n
+
+ Example::
+
+ >>> [int(eulernum(n)) for n in range(11)]
+ [1, 0, -1, 0, 5, 0, -61, 0, 1385, 0, -50521]
+ >>> [int(eulernum(n)) for n in range(11)] # test cache
+ [1, 0, -1, 0, 5, 0, -61, 0, 1385, 0, -50521]
+
+ """
+ # for odd m > 1, the Euler numbers are zero
+ if m & 1:
+ return MPZ_ZERO
+ f = _cache.get(m)
+ if f:
+ return f
+ MAX = MAX_EULER_CACHE
+ n = m
+ a = [MPZ(_) for _ in [0,0,1,0,0,0]]
+ for n in range(1, m+1):
+ for j in range(n+1, -1, -2):
+ a[j+1] = (j-1)*a[j] + (j+1)*a[j+2]
+ a.append(0)
+ suma = 0
+ for k in range(n+1, -1, -2):
+ suma += a[k+1]
+ if n <= MAX:
+ _cache[n] = ((-1)**(n//2))*(suma // 2**n)
+ if n == m:
+ return ((-1)**(n//2))*suma // 2**n
+
+def stirling1(n, k):
+ """
+ Stirling number of the first kind.
+ """
+ if n < 0 or k < 0:
+ raise ValueError
+ if k >= n:
+ return MPZ(n == k)
+ if k < 1:
+ return MPZ_ZERO
+ L = [MPZ_ZERO] * (k+1)
+ L[1] = MPZ_ONE
+ for m in xrange(2, n+1):
+ for j in xrange(min(k, m), 0, -1):
+ L[j] = (m-1) * L[j] + L[j-1]
+ return (-1)**(n+k) * L[k]
+
+def stirling2(n, k):
+ """
+ Stirling number of the second kind.
+ """
+ if n < 0 or k < 0:
+ raise ValueError
+ if k >= n:
+ return MPZ(n == k)
+ if k <= 1:
+ return MPZ(k == 1)
+ s = MPZ_ZERO
+ t = MPZ_ONE
+ for j in xrange(k+1):
+ if (k + j) & 1:
+ s -= t * MPZ(j)**n
+ else:
+ s += t * MPZ(j)**n
+ t = t * (k - j) // (j + 1)
+ return s // ifac(k)
diff --git a/lib/python3.10/site-packages/mpmath/libmp/libmpc.py b/lib/python3.10/site-packages/mpmath/libmp/libmpc.py
new file mode 100644
index 0000000000000000000000000000000000000000..cc22d0e73674676c8a9249ebc2d48da7f3be8b0d
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/libmp/libmpc.py
@@ -0,0 +1,835 @@
+"""
+Low-level functions for complex arithmetic.
+"""
+
+import sys
+
+from .backend import MPZ, MPZ_ZERO, MPZ_ONE, MPZ_TWO, BACKEND
+
+from .libmpf import (\
+ round_floor, round_ceiling, round_down, round_up,
+ round_nearest, round_fast, bitcount,
+ bctable, normalize, normalize1, reciprocal_rnd, rshift, lshift, giant_steps,
+ negative_rnd,
+ to_str, to_fixed, from_man_exp, from_float, to_float, from_int, to_int,
+ fzero, fone, ftwo, fhalf, finf, fninf, fnan, fnone,
+ mpf_abs, mpf_pos, mpf_neg, mpf_add, mpf_sub, mpf_mul,
+ mpf_div, mpf_mul_int, mpf_shift, mpf_sqrt, mpf_hypot,
+ mpf_rdiv_int, mpf_floor, mpf_ceil, mpf_nint, mpf_frac,
+ mpf_sign, mpf_hash,
+ ComplexResult
+)
+
+from .libelefun import (\
+ mpf_pi, mpf_exp, mpf_log, mpf_cos_sin, mpf_cosh_sinh, mpf_tan, mpf_pow_int,
+ mpf_log_hypot,
+ mpf_cos_sin_pi, mpf_phi,
+ mpf_cos, mpf_sin, mpf_cos_pi, mpf_sin_pi,
+ mpf_atan, mpf_atan2, mpf_cosh, mpf_sinh, mpf_tanh,
+ mpf_asin, mpf_acos, mpf_acosh, mpf_nthroot, mpf_fibonacci
+)
+
+# An mpc value is a (real, imag) tuple
+mpc_one = fone, fzero
+mpc_zero = fzero, fzero
+mpc_two = ftwo, fzero
+mpc_half = (fhalf, fzero)
+
+_infs = (finf, fninf)
+_infs_nan = (finf, fninf, fnan)
+
+def mpc_is_inf(z):
+ """Check if either real or imaginary part is infinite"""
+ re, im = z
+ if re in _infs: return True
+ if im in _infs: return True
+ return False
+
+def mpc_is_infnan(z):
+ """Check if either real or imaginary part is infinite or nan"""
+ re, im = z
+ if re in _infs_nan: return True
+ if im in _infs_nan: return True
+ return False
+
+def mpc_to_str(z, dps, **kwargs):
+ re, im = z
+ rs = to_str(re, dps)
+ if im[0]:
+ return rs + " - " + to_str(mpf_neg(im), dps, **kwargs) + "j"
+ else:
+ return rs + " + " + to_str(im, dps, **kwargs) + "j"
+
+def mpc_to_complex(z, strict=False, rnd=round_fast):
+ re, im = z
+ return complex(to_float(re, strict, rnd), to_float(im, strict, rnd))
+
+def mpc_hash(z):
+ if sys.version_info >= (3, 2):
+ re, im = z
+ h = mpf_hash(re) + sys.hash_info.imag * mpf_hash(im)
+ # Need to reduce either module 2^32 or 2^64
+ h = h % (2**sys.hash_info.width)
+ return int(h)
+ else:
+ try:
+ return hash(mpc_to_complex(z, strict=True))
+ except OverflowError:
+ return hash(z)
+
+def mpc_conjugate(z, prec, rnd=round_fast):
+ re, im = z
+ return re, mpf_neg(im, prec, rnd)
+
+def mpc_is_nonzero(z):
+ return z != mpc_zero
+
+def mpc_add(z, w, prec, rnd=round_fast):
+ a, b = z
+ c, d = w
+ return mpf_add(a, c, prec, rnd), mpf_add(b, d, prec, rnd)
+
+def mpc_add_mpf(z, x, prec, rnd=round_fast):
+ a, b = z
+ return mpf_add(a, x, prec, rnd), b
+
+def mpc_sub(z, w, prec=0, rnd=round_fast):
+ a, b = z
+ c, d = w
+ return mpf_sub(a, c, prec, rnd), mpf_sub(b, d, prec, rnd)
+
+def mpc_sub_mpf(z, p, prec=0, rnd=round_fast):
+ a, b = z
+ return mpf_sub(a, p, prec, rnd), b
+
+def mpc_pos(z, prec, rnd=round_fast):
+ a, b = z
+ return mpf_pos(a, prec, rnd), mpf_pos(b, prec, rnd)
+
+def mpc_neg(z, prec=None, rnd=round_fast):
+ a, b = z
+ return mpf_neg(a, prec, rnd), mpf_neg(b, prec, rnd)
+
+def mpc_shift(z, n):
+ a, b = z
+ return mpf_shift(a, n), mpf_shift(b, n)
+
+def mpc_abs(z, prec, rnd=round_fast):
+ """Absolute value of a complex number, |a+bi|.
+ Returns an mpf value."""
+ a, b = z
+ return mpf_hypot(a, b, prec, rnd)
+
+def mpc_arg(z, prec, rnd=round_fast):
+ """Argument of a complex number. Returns an mpf value."""
+ a, b = z
+ return mpf_atan2(b, a, prec, rnd)
+
+def mpc_floor(z, prec, rnd=round_fast):
+ a, b = z
+ return mpf_floor(a, prec, rnd), mpf_floor(b, prec, rnd)
+
+def mpc_ceil(z, prec, rnd=round_fast):
+ a, b = z
+ return mpf_ceil(a, prec, rnd), mpf_ceil(b, prec, rnd)
+
+def mpc_nint(z, prec, rnd=round_fast):
+ a, b = z
+ return mpf_nint(a, prec, rnd), mpf_nint(b, prec, rnd)
+
+def mpc_frac(z, prec, rnd=round_fast):
+ a, b = z
+ return mpf_frac(a, prec, rnd), mpf_frac(b, prec, rnd)
+
+
+def mpc_mul(z, w, prec, rnd=round_fast):
+ """
+ Complex multiplication.
+
+ Returns the real and imaginary part of (a+bi)*(c+di), rounded to
+ the specified precision. The rounding mode applies to the real and
+ imaginary parts separately.
+ """
+ a, b = z
+ c, d = w
+ p = mpf_mul(a, c)
+ q = mpf_mul(b, d)
+ r = mpf_mul(a, d)
+ s = mpf_mul(b, c)
+ re = mpf_sub(p, q, prec, rnd)
+ im = mpf_add(r, s, prec, rnd)
+ return re, im
+
+def mpc_square(z, prec, rnd=round_fast):
+ # (a+b*I)**2 == a**2 - b**2 + 2*I*a*b
+ a, b = z
+ p = mpf_mul(a,a)
+ q = mpf_mul(b,b)
+ r = mpf_mul(a,b, prec, rnd)
+ re = mpf_sub(p, q, prec, rnd)
+ im = mpf_shift(r, 1)
+ return re, im
+
+def mpc_mul_mpf(z, p, prec, rnd=round_fast):
+ a, b = z
+ re = mpf_mul(a, p, prec, rnd)
+ im = mpf_mul(b, p, prec, rnd)
+ return re, im
+
+def mpc_mul_imag_mpf(z, x, prec, rnd=round_fast):
+ """
+ Multiply the mpc value z by I*x where x is an mpf value.
+ """
+ a, b = z
+ re = mpf_neg(mpf_mul(b, x, prec, rnd))
+ im = mpf_mul(a, x, prec, rnd)
+ return re, im
+
+def mpc_mul_int(z, n, prec, rnd=round_fast):
+ a, b = z
+ re = mpf_mul_int(a, n, prec, rnd)
+ im = mpf_mul_int(b, n, prec, rnd)
+ return re, im
+
+def mpc_div(z, w, prec, rnd=round_fast):
+ a, b = z
+ c, d = w
+ wp = prec + 10
+ # mag = c*c + d*d
+ mag = mpf_add(mpf_mul(c, c), mpf_mul(d, d), wp)
+ # (a*c+b*d)/mag, (b*c-a*d)/mag
+ t = mpf_add(mpf_mul(a,c), mpf_mul(b,d), wp)
+ u = mpf_sub(mpf_mul(b,c), mpf_mul(a,d), wp)
+ return mpf_div(t,mag,prec,rnd), mpf_div(u,mag,prec,rnd)
+
+def mpc_div_mpf(z, p, prec, rnd=round_fast):
+ """Calculate z/p where p is real"""
+ a, b = z
+ re = mpf_div(a, p, prec, rnd)
+ im = mpf_div(b, p, prec, rnd)
+ return re, im
+
+def mpc_reciprocal(z, prec, rnd=round_fast):
+ """Calculate 1/z efficiently"""
+ a, b = z
+ m = mpf_add(mpf_mul(a,a),mpf_mul(b,b),prec+10)
+ re = mpf_div(a, m, prec, rnd)
+ im = mpf_neg(mpf_div(b, m, prec, rnd))
+ return re, im
+
+def mpc_mpf_div(p, z, prec, rnd=round_fast):
+ """Calculate p/z where p is real efficiently"""
+ a, b = z
+ m = mpf_add(mpf_mul(a,a),mpf_mul(b,b), prec+10)
+ re = mpf_div(mpf_mul(a,p), m, prec, rnd)
+ im = mpf_div(mpf_neg(mpf_mul(b,p)), m, prec, rnd)
+ return re, im
+
+def complex_int_pow(a, b, n):
+ """Complex integer power: computes (a+b*I)**n exactly for
+ nonnegative n (a and b must be Python ints)."""
+ wre = 1
+ wim = 0
+ while n:
+ if n & 1:
+ wre, wim = wre*a - wim*b, wim*a + wre*b
+ n -= 1
+ a, b = a*a - b*b, 2*a*b
+ n //= 2
+ return wre, wim
+
+def mpc_pow(z, w, prec, rnd=round_fast):
+ if w[1] == fzero:
+ return mpc_pow_mpf(z, w[0], prec, rnd)
+ return mpc_exp(mpc_mul(mpc_log(z, prec+10), w, prec+10), prec, rnd)
+
+def mpc_pow_mpf(z, p, prec, rnd=round_fast):
+ psign, pman, pexp, pbc = p
+ if pexp >= 0:
+ return mpc_pow_int(z, (-1)**psign * (pman< 0:
+ aman <<= de
+ aexp = bexp
+ else:
+ bman <<= (-de)
+ bexp = aexp
+ re, im = complex_int_pow(aman, bman, n)
+ re = from_man_exp(re, int(n*aexp), prec, rnd)
+ im = from_man_exp(im, int(n*bexp), prec, rnd)
+ return re, im
+ return mpc_exp(mpc_mul_int(mpc_log(z, prec+10), n, prec+10), prec, rnd)
+
+def mpc_sqrt(z, prec, rnd=round_fast):
+ """Complex square root (principal branch).
+
+ We have sqrt(a+bi) = sqrt((r+a)/2) + b/sqrt(2*(r+a))*i where
+ r = abs(a+bi), when a+bi is not a negative real number."""
+ a, b = z
+ if b == fzero:
+ if a == fzero:
+ return (a, b)
+ # When a+bi is a negative real number, we get a real sqrt times i
+ if a[0]:
+ im = mpf_sqrt(mpf_neg(a), prec, rnd)
+ return (fzero, im)
+ else:
+ re = mpf_sqrt(a, prec, rnd)
+ return (re, fzero)
+ wp = prec+20
+ if not a[0]: # case a positive
+ t = mpf_add(mpc_abs((a, b), wp), a, wp) # t = abs(a+bi) + a
+ u = mpf_shift(t, -1) # u = t/2
+ re = mpf_sqrt(u, prec, rnd) # re = sqrt(u)
+ v = mpf_shift(t, 1) # v = 2*t
+ w = mpf_sqrt(v, wp) # w = sqrt(v)
+ im = mpf_div(b, w, prec, rnd) # im = b / w
+ else: # case a negative
+ t = mpf_sub(mpc_abs((a, b), wp), a, wp) # t = abs(a+bi) - a
+ u = mpf_shift(t, -1) # u = t/2
+ im = mpf_sqrt(u, prec, rnd) # im = sqrt(u)
+ v = mpf_shift(t, 1) # v = 2*t
+ w = mpf_sqrt(v, wp) # w = sqrt(v)
+ re = mpf_div(b, w, prec, rnd) # re = b/w
+ if b[0]:
+ re = mpf_neg(re)
+ im = mpf_neg(im)
+ return re, im
+
+def mpc_nthroot_fixed(a, b, n, prec):
+ # a, b signed integers at fixed precision prec
+ start = 50
+ a1 = int(rshift(a, prec - n*start))
+ b1 = int(rshift(b, prec - n*start))
+ try:
+ r = (a1 + 1j * b1)**(1.0/n)
+ re = r.real
+ im = r.imag
+ re = MPZ(int(re))
+ im = MPZ(int(im))
+ except OverflowError:
+ a1 = from_int(a1, start)
+ b1 = from_int(b1, start)
+ fn = from_int(n)
+ nth = mpf_rdiv_int(1, fn, start)
+ re, im = mpc_pow((a1, b1), (nth, fzero), start)
+ re = to_int(re)
+ im = to_int(im)
+ extra = 10
+ prevp = start
+ extra1 = n
+ for p in giant_steps(start, prec+extra):
+ # this is slow for large n, unlike int_pow_fixed
+ re2, im2 = complex_int_pow(re, im, n-1)
+ re2 = rshift(re2, (n-1)*prevp - p - extra1)
+ im2 = rshift(im2, (n-1)*prevp - p - extra1)
+ r4 = (re2*re2 + im2*im2) >> (p + extra1)
+ ap = rshift(a, prec - p)
+ bp = rshift(b, prec - p)
+ rec = (ap * re2 + bp * im2) >> p
+ imc = (-ap * im2 + bp * re2) >> p
+ reb = (rec << p) // r4
+ imb = (imc << p) // r4
+ re = (reb + (n-1)*lshift(re, p-prevp))//n
+ im = (imb + (n-1)*lshift(im, p-prevp))//n
+ prevp = p
+ return re, im
+
+def mpc_nthroot(z, n, prec, rnd=round_fast):
+ """
+ Complex n-th root.
+
+ Use Newton method as in the real case when it is faster,
+ otherwise use z**(1/n)
+ """
+ a, b = z
+ if a[0] == 0 and b == fzero:
+ re = mpf_nthroot(a, n, prec, rnd)
+ return (re, fzero)
+ if n < 2:
+ if n == 0:
+ return mpc_one
+ if n == 1:
+ return mpc_pos((a, b), prec, rnd)
+ if n == -1:
+ return mpc_div(mpc_one, (a, b), prec, rnd)
+ inverse = mpc_nthroot((a, b), -n, prec+5, reciprocal_rnd[rnd])
+ return mpc_div(mpc_one, inverse, prec, rnd)
+ if n <= 20:
+ prec2 = int(1.2 * (prec + 10))
+ asign, aman, aexp, abc = a
+ bsign, bman, bexp, bbc = b
+ pf = mpc_abs((a,b), prec)
+ if pf[-2] + pf[-1] > -10 and pf[-2] + pf[-1] < prec:
+ af = to_fixed(a, prec2)
+ bf = to_fixed(b, prec2)
+ re, im = mpc_nthroot_fixed(af, bf, n, prec2)
+ extra = 10
+ re = from_man_exp(re, -prec2-extra, prec2, rnd)
+ im = from_man_exp(im, -prec2-extra, prec2, rnd)
+ return re, im
+ fn = from_int(n)
+ prec2 = prec+10 + 10
+ nth = mpf_rdiv_int(1, fn, prec2)
+ re, im = mpc_pow((a, b), (nth, fzero), prec2, rnd)
+ re = normalize(re[0], re[1], re[2], re[3], prec, rnd)
+ im = normalize(im[0], im[1], im[2], im[3], prec, rnd)
+ return re, im
+
+def mpc_cbrt(z, prec, rnd=round_fast):
+ """
+ Complex cubic root.
+ """
+ return mpc_nthroot(z, 3, prec, rnd)
+
+def mpc_exp(z, prec, rnd=round_fast):
+ """
+ Complex exponential function.
+
+ We use the direct formula exp(a+bi) = exp(a) * (cos(b) + sin(b)*i)
+ for the computation. This formula is very nice because it is
+ pefectly stable; since we just do real multiplications, the only
+ numerical errors that can creep in are single-ulp rounding errors.
+
+ The formula is efficient since mpmath's real exp is quite fast and
+ since we can compute cos and sin simultaneously.
+
+ It is no problem if a and b are large; if the implementations of
+ exp/cos/sin are accurate and efficient for all real numbers, then
+ so is this function for all complex numbers.
+ """
+ a, b = z
+ if a == fzero:
+ return mpf_cos_sin(b, prec, rnd)
+ if b == fzero:
+ return mpf_exp(a, prec, rnd), fzero
+ mag = mpf_exp(a, prec+4, rnd)
+ c, s = mpf_cos_sin(b, prec+4, rnd)
+ re = mpf_mul(mag, c, prec, rnd)
+ im = mpf_mul(mag, s, prec, rnd)
+ return re, im
+
+def mpc_log(z, prec, rnd=round_fast):
+ re = mpf_log_hypot(z[0], z[1], prec, rnd)
+ im = mpc_arg(z, prec, rnd)
+ return re, im
+
+def mpc_cos(z, prec, rnd=round_fast):
+ """Complex cosine. The formula used is cos(a+bi) = cos(a)*cosh(b) -
+ sin(a)*sinh(b)*i.
+
+ The same comments apply as for the complex exp: only real
+ multiplications are pewrormed, so no cancellation errors are
+ possible. The formula is also efficient since we can compute both
+ pairs (cos, sin) and (cosh, sinh) in single stwps."""
+ a, b = z
+ if b == fzero:
+ return mpf_cos(a, prec, rnd), fzero
+ if a == fzero:
+ return mpf_cosh(b, prec, rnd), fzero
+ wp = prec + 6
+ c, s = mpf_cos_sin(a, wp)
+ ch, sh = mpf_cosh_sinh(b, wp)
+ re = mpf_mul(c, ch, prec, rnd)
+ im = mpf_mul(s, sh, prec, rnd)
+ return re, mpf_neg(im)
+
+def mpc_sin(z, prec, rnd=round_fast):
+ """Complex sine. We have sin(a+bi) = sin(a)*cosh(b) +
+ cos(a)*sinh(b)*i. See the docstring for mpc_cos for additional
+ comments."""
+ a, b = z
+ if b == fzero:
+ return mpf_sin(a, prec, rnd), fzero
+ if a == fzero:
+ return fzero, mpf_sinh(b, prec, rnd)
+ wp = prec + 6
+ c, s = mpf_cos_sin(a, wp)
+ ch, sh = mpf_cosh_sinh(b, wp)
+ re = mpf_mul(s, ch, prec, rnd)
+ im = mpf_mul(c, sh, prec, rnd)
+ return re, im
+
+def mpc_tan(z, prec, rnd=round_fast):
+ """Complex tangent. Computed as tan(a+bi) = sin(2a)/M + sinh(2b)/M*i
+ where M = cos(2a) + cosh(2b)."""
+ a, b = z
+ asign, aman, aexp, abc = a
+ bsign, bman, bexp, bbc = b
+ if b == fzero: return mpf_tan(a, prec, rnd), fzero
+ if a == fzero: return fzero, mpf_tanh(b, prec, rnd)
+ wp = prec + 15
+ a = mpf_shift(a, 1)
+ b = mpf_shift(b, 1)
+ c, s = mpf_cos_sin(a, wp)
+ ch, sh = mpf_cosh_sinh(b, wp)
+ # TODO: handle cancellation when c ~= -1 and ch ~= 1
+ mag = mpf_add(c, ch, wp)
+ re = mpf_div(s, mag, prec, rnd)
+ im = mpf_div(sh, mag, prec, rnd)
+ return re, im
+
+def mpc_cos_pi(z, prec, rnd=round_fast):
+ a, b = z
+ if b == fzero:
+ return mpf_cos_pi(a, prec, rnd), fzero
+ b = mpf_mul(b, mpf_pi(prec+5), prec+5)
+ if a == fzero:
+ return mpf_cosh(b, prec, rnd), fzero
+ wp = prec + 6
+ c, s = mpf_cos_sin_pi(a, wp)
+ ch, sh = mpf_cosh_sinh(b, wp)
+ re = mpf_mul(c, ch, prec, rnd)
+ im = mpf_mul(s, sh, prec, rnd)
+ return re, mpf_neg(im)
+
+def mpc_sin_pi(z, prec, rnd=round_fast):
+ a, b = z
+ if b == fzero:
+ return mpf_sin_pi(a, prec, rnd), fzero
+ b = mpf_mul(b, mpf_pi(prec+5), prec+5)
+ if a == fzero:
+ return fzero, mpf_sinh(b, prec, rnd)
+ wp = prec + 6
+ c, s = mpf_cos_sin_pi(a, wp)
+ ch, sh = mpf_cosh_sinh(b, wp)
+ re = mpf_mul(s, ch, prec, rnd)
+ im = mpf_mul(c, sh, prec, rnd)
+ return re, im
+
+def mpc_cos_sin(z, prec, rnd=round_fast):
+ a, b = z
+ if a == fzero:
+ ch, sh = mpf_cosh_sinh(b, prec, rnd)
+ return (ch, fzero), (fzero, sh)
+ if b == fzero:
+ c, s = mpf_cos_sin(a, prec, rnd)
+ return (c, fzero), (s, fzero)
+ wp = prec + 6
+ c, s = mpf_cos_sin(a, wp)
+ ch, sh = mpf_cosh_sinh(b, wp)
+ cre = mpf_mul(c, ch, prec, rnd)
+ cim = mpf_mul(s, sh, prec, rnd)
+ sre = mpf_mul(s, ch, prec, rnd)
+ sim = mpf_mul(c, sh, prec, rnd)
+ return (cre, mpf_neg(cim)), (sre, sim)
+
+def mpc_cos_sin_pi(z, prec, rnd=round_fast):
+ a, b = z
+ if b == fzero:
+ c, s = mpf_cos_sin_pi(a, prec, rnd)
+ return (c, fzero), (s, fzero)
+ b = mpf_mul(b, mpf_pi(prec+5), prec+5)
+ if a == fzero:
+ ch, sh = mpf_cosh_sinh(b, prec, rnd)
+ return (ch, fzero), (fzero, sh)
+ wp = prec + 6
+ c, s = mpf_cos_sin_pi(a, wp)
+ ch, sh = mpf_cosh_sinh(b, wp)
+ cre = mpf_mul(c, ch, prec, rnd)
+ cim = mpf_mul(s, sh, prec, rnd)
+ sre = mpf_mul(s, ch, prec, rnd)
+ sim = mpf_mul(c, sh, prec, rnd)
+ return (cre, mpf_neg(cim)), (sre, sim)
+
+def mpc_cosh(z, prec, rnd=round_fast):
+ """Complex hyperbolic cosine. Computed as cosh(z) = cos(z*i)."""
+ a, b = z
+ return mpc_cos((b, mpf_neg(a)), prec, rnd)
+
+def mpc_sinh(z, prec, rnd=round_fast):
+ """Complex hyperbolic sine. Computed as sinh(z) = -i*sin(z*i)."""
+ a, b = z
+ b, a = mpc_sin((b, a), prec, rnd)
+ return a, b
+
+def mpc_tanh(z, prec, rnd=round_fast):
+ """Complex hyperbolic tangent. Computed as tanh(z) = -i*tan(z*i)."""
+ a, b = z
+ b, a = mpc_tan((b, a), prec, rnd)
+ return a, b
+
+# TODO: avoid loss of accuracy
+def mpc_atan(z, prec, rnd=round_fast):
+ a, b = z
+ # atan(z) = (I/2)*(log(1-I*z) - log(1+I*z))
+ # x = 1-I*z = 1 + b - I*a
+ # y = 1+I*z = 1 - b + I*a
+ wp = prec + 15
+ x = mpf_add(fone, b, wp), mpf_neg(a)
+ y = mpf_sub(fone, b, wp), a
+ l1 = mpc_log(x, wp)
+ l2 = mpc_log(y, wp)
+ a, b = mpc_sub(l1, l2, prec, rnd)
+ # (I/2) * (a+b*I) = (-b/2 + a/2*I)
+ v = mpf_neg(mpf_shift(b,-1)), mpf_shift(a,-1)
+ # Subtraction at infinity gives correct real part but
+ # wrong imaginary part (should be zero)
+ if v[1] == fnan and mpc_is_inf(z):
+ v = (v[0], fzero)
+ return v
+
+beta_crossover = from_float(0.6417)
+alpha_crossover = from_float(1.5)
+
+def acos_asin(z, prec, rnd, n):
+ """ complex acos for n = 0, asin for n = 1
+ The algorithm is described in
+ T.E. Hull, T.F. Fairgrieve and P.T.P. Tang
+ 'Implementing the Complex Arcsine and Arcosine Functions
+ using Exception Handling',
+ ACM Trans. on Math. Software Vol. 23 (1997), p299
+ The complex acos and asin can be defined as
+ acos(z) = acos(beta) - I*sign(a)* log(alpha + sqrt(alpha**2 -1))
+ asin(z) = asin(beta) + I*sign(a)* log(alpha + sqrt(alpha**2 -1))
+ where z = a + I*b
+ alpha = (1/2)*(r + s); beta = (1/2)*(r - s) = a/alpha
+ r = sqrt((a+1)**2 + y**2); s = sqrt((a-1)**2 + y**2)
+ These expressions are rewritten in different ways in different
+ regions, delimited by two crossovers alpha_crossover and beta_crossover,
+ and by abs(a) <= 1, in order to improve the numerical accuracy.
+ """
+ a, b = z
+ wp = prec + 10
+ # special cases with real argument
+ if b == fzero:
+ am = mpf_sub(fone, mpf_abs(a), wp)
+ # case abs(a) <= 1
+ if not am[0]:
+ if n == 0:
+ return mpf_acos(a, prec, rnd), fzero
+ else:
+ return mpf_asin(a, prec, rnd), fzero
+ # cases abs(a) > 1
+ else:
+ # case a < -1
+ if a[0]:
+ pi = mpf_pi(prec, rnd)
+ c = mpf_acosh(mpf_neg(a), prec, rnd)
+ if n == 0:
+ return pi, mpf_neg(c)
+ else:
+ return mpf_neg(mpf_shift(pi, -1)), c
+ # case a > 1
+ else:
+ c = mpf_acosh(a, prec, rnd)
+ if n == 0:
+ return fzero, c
+ else:
+ pi = mpf_pi(prec, rnd)
+ return mpf_shift(pi, -1), mpf_neg(c)
+ asign = bsign = 0
+ if a[0]:
+ a = mpf_neg(a)
+ asign = 1
+ if b[0]:
+ b = mpf_neg(b)
+ bsign = 1
+ am = mpf_sub(fone, a, wp)
+ ap = mpf_add(fone, a, wp)
+ r = mpf_hypot(ap, b, wp)
+ s = mpf_hypot(am, b, wp)
+ alpha = mpf_shift(mpf_add(r, s, wp), -1)
+ beta = mpf_div(a, alpha, wp)
+ b2 = mpf_mul(b,b, wp)
+ # case beta <= beta_crossover
+ if not mpf_sub(beta_crossover, beta, wp)[0]:
+ if n == 0:
+ re = mpf_acos(beta, wp)
+ else:
+ re = mpf_asin(beta, wp)
+ else:
+ # to compute the real part in this region use the identity
+ # asin(beta) = atan(beta/sqrt(1-beta**2))
+ # beta/sqrt(1-beta**2) = (alpha + a) * (alpha - a)
+ # alpha + a is numerically accurate; alpha - a can have
+ # cancellations leading to numerical inaccuracies, so rewrite
+ # it in differente ways according to the region
+ Ax = mpf_add(alpha, a, wp)
+ # case a <= 1
+ if not am[0]:
+ # c = b*b/(r + (a+1)); d = (s + (1-a))
+ # alpha - a = (1/2)*(c + d)
+ # case n=0: re = atan(sqrt((1/2) * Ax * (c + d))/a)
+ # case n=1: re = atan(a/sqrt((1/2) * Ax * (c + d)))
+ c = mpf_div(b2, mpf_add(r, ap, wp), wp)
+ d = mpf_add(s, am, wp)
+ re = mpf_shift(mpf_mul(Ax, mpf_add(c, d, wp), wp), -1)
+ if n == 0:
+ re = mpf_atan(mpf_div(mpf_sqrt(re, wp), a, wp), wp)
+ else:
+ re = mpf_atan(mpf_div(a, mpf_sqrt(re, wp), wp), wp)
+ else:
+ # c = Ax/(r + (a+1)); d = Ax/(s - (1-a))
+ # alpha - a = (1/2)*(c + d)
+ # case n = 0: re = atan(b*sqrt(c + d)/2/a)
+ # case n = 1: re = atan(a/(b*sqrt(c + d)/2)
+ c = mpf_div(Ax, mpf_add(r, ap, wp), wp)
+ d = mpf_div(Ax, mpf_sub(s, am, wp), wp)
+ re = mpf_shift(mpf_add(c, d, wp), -1)
+ re = mpf_mul(b, mpf_sqrt(re, wp), wp)
+ if n == 0:
+ re = mpf_atan(mpf_div(re, a, wp), wp)
+ else:
+ re = mpf_atan(mpf_div(a, re, wp), wp)
+ # to compute alpha + sqrt(alpha**2 - 1), if alpha <= alpha_crossover
+ # replace it with 1 + Am1 + sqrt(Am1*(alpha+1)))
+ # where Am1 = alpha -1
+ # if alpha <= alpha_crossover:
+ if not mpf_sub(alpha_crossover, alpha, wp)[0]:
+ c1 = mpf_div(b2, mpf_add(r, ap, wp), wp)
+ # case a < 1
+ if mpf_neg(am)[0]:
+ # Am1 = (1/2) * (b*b/(r + (a+1)) + b*b/(s + (1-a))
+ c2 = mpf_add(s, am, wp)
+ c2 = mpf_div(b2, c2, wp)
+ Am1 = mpf_shift(mpf_add(c1, c2, wp), -1)
+ else:
+ # Am1 = (1/2) * (b*b/(r + (a+1)) + (s - (1-a)))
+ c2 = mpf_sub(s, am, wp)
+ Am1 = mpf_shift(mpf_add(c1, c2, wp), -1)
+ # im = log(1 + Am1 + sqrt(Am1*(alpha+1)))
+ im = mpf_mul(Am1, mpf_add(alpha, fone, wp), wp)
+ im = mpf_log(mpf_add(fone, mpf_add(Am1, mpf_sqrt(im, wp), wp), wp), wp)
+ else:
+ # im = log(alpha + sqrt(alpha*alpha - 1))
+ im = mpf_sqrt(mpf_sub(mpf_mul(alpha, alpha, wp), fone, wp), wp)
+ im = mpf_log(mpf_add(alpha, im, wp), wp)
+ if asign:
+ if n == 0:
+ re = mpf_sub(mpf_pi(wp), re, wp)
+ else:
+ re = mpf_neg(re)
+ if not bsign and n == 0:
+ im = mpf_neg(im)
+ if bsign and n == 1:
+ im = mpf_neg(im)
+ re = normalize(re[0], re[1], re[2], re[3], prec, rnd)
+ im = normalize(im[0], im[1], im[2], im[3], prec, rnd)
+ return re, im
+
+def mpc_acos(z, prec, rnd=round_fast):
+ return acos_asin(z, prec, rnd, 0)
+
+def mpc_asin(z, prec, rnd=round_fast):
+ return acos_asin(z, prec, rnd, 1)
+
+def mpc_asinh(z, prec, rnd=round_fast):
+ # asinh(z) = I * asin(-I z)
+ a, b = z
+ a, b = mpc_asin((b, mpf_neg(a)), prec, rnd)
+ return mpf_neg(b), a
+
+def mpc_acosh(z, prec, rnd=round_fast):
+ # acosh(z) = -I * acos(z) for Im(acos(z)) <= 0
+ # +I * acos(z) otherwise
+ a, b = mpc_acos(z, prec, rnd)
+ if b[0] or b == fzero:
+ return mpf_neg(b), a
+ else:
+ return b, mpf_neg(a)
+
+def mpc_atanh(z, prec, rnd=round_fast):
+ # atanh(z) = (log(1+z)-log(1-z))/2
+ wp = prec + 15
+ a = mpc_add(z, mpc_one, wp)
+ b = mpc_sub(mpc_one, z, wp)
+ a = mpc_log(a, wp)
+ b = mpc_log(b, wp)
+ v = mpc_shift(mpc_sub(a, b, wp), -1)
+ # Subtraction at infinity gives correct imaginary part but
+ # wrong real part (should be zero)
+ if v[0] == fnan and mpc_is_inf(z):
+ v = (fzero, v[1])
+ return v
+
+def mpc_fibonacci(z, prec, rnd=round_fast):
+ re, im = z
+ if im == fzero:
+ return (mpf_fibonacci(re, prec, rnd), fzero)
+ size = max(abs(re[2]+re[3]), abs(re[2]+re[3]))
+ wp = prec + size + 20
+ a = mpf_phi(wp)
+ b = mpf_add(mpf_shift(a, 1), fnone, wp)
+ u = mpc_pow((a, fzero), z, wp)
+ v = mpc_cos_pi(z, wp)
+ v = mpc_div(v, u, wp)
+ u = mpc_sub(u, v, wp)
+ u = mpc_div_mpf(u, b, prec, rnd)
+ return u
+
+def mpf_expj(x, prec, rnd='f'):
+ raise ComplexResult
+
+def mpc_expj(z, prec, rnd='f'):
+ re, im = z
+ if im == fzero:
+ return mpf_cos_sin(re, prec, rnd)
+ if re == fzero:
+ return mpf_exp(mpf_neg(im), prec, rnd), fzero
+ ey = mpf_exp(mpf_neg(im), prec+10)
+ c, s = mpf_cos_sin(re, prec+10)
+ re = mpf_mul(ey, c, prec, rnd)
+ im = mpf_mul(ey, s, prec, rnd)
+ return re, im
+
+def mpf_expjpi(x, prec, rnd='f'):
+ raise ComplexResult
+
+def mpc_expjpi(z, prec, rnd='f'):
+ re, im = z
+ if im == fzero:
+ return mpf_cos_sin_pi(re, prec, rnd)
+ sign, man, exp, bc = im
+ wp = prec+10
+ if man:
+ wp += max(0, exp+bc)
+ im = mpf_neg(mpf_mul(mpf_pi(wp), im, wp))
+ if re == fzero:
+ return mpf_exp(im, prec, rnd), fzero
+ ey = mpf_exp(im, prec+10)
+ c, s = mpf_cos_sin_pi(re, prec+10)
+ re = mpf_mul(ey, c, prec, rnd)
+ im = mpf_mul(ey, s, prec, rnd)
+ return re, im
+
+
+if BACKEND == 'sage':
+ try:
+ import sage.libs.mpmath.ext_libmp as _lbmp
+ mpc_exp = _lbmp.mpc_exp
+ mpc_sqrt = _lbmp.mpc_sqrt
+ except (ImportError, AttributeError):
+ print("Warning: Sage imports in libmpc failed")
diff --git a/lib/python3.10/site-packages/mpmath/libmp/libmpf.py b/lib/python3.10/site-packages/mpmath/libmp/libmpf.py
new file mode 100644
index 0000000000000000000000000000000000000000..5c162e17d4f688c71dc3476b944e2d31c65faab7
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/libmp/libmpf.py
@@ -0,0 +1,1414 @@
+"""
+Low-level functions for arbitrary-precision floating-point arithmetic.
+"""
+
+__docformat__ = 'plaintext'
+
+import math
+
+from bisect import bisect
+
+import sys
+
+# Importing random is slow
+#from random import getrandbits
+getrandbits = None
+
+from .backend import (MPZ, MPZ_TYPE, MPZ_ZERO, MPZ_ONE, MPZ_TWO, MPZ_FIVE,
+ BACKEND, STRICT, HASH_MODULUS, HASH_BITS, gmpy, sage, sage_utils)
+
+from .libintmath import (giant_steps,
+ trailtable, bctable, lshift, rshift, bitcount, trailing,
+ sqrt_fixed, numeral, isqrt, isqrt_fast, sqrtrem,
+ bin_to_radix)
+
+# We don't pickle tuples directly for the following reasons:
+# 1: pickle uses str() for ints, which is inefficient when they are large
+# 2: pickle doesn't work for gmpy mpzs
+# Both problems are solved by using hex()
+
+if BACKEND == 'sage':
+ def to_pickable(x):
+ sign, man, exp, bc = x
+ return sign, hex(man), exp, bc
+else:
+ def to_pickable(x):
+ sign, man, exp, bc = x
+ return sign, hex(man)[2:], exp, bc
+
+def from_pickable(x):
+ sign, man, exp, bc = x
+ return (sign, MPZ(man, 16), exp, bc)
+
+class ComplexResult(ValueError):
+ pass
+
+try:
+ intern
+except NameError:
+ intern = lambda x: x
+
+# All supported rounding modes
+round_nearest = intern('n')
+round_floor = intern('f')
+round_ceiling = intern('c')
+round_up = intern('u')
+round_down = intern('d')
+round_fast = round_down
+
+def prec_to_dps(n):
+ """Return number of accurate decimals that can be represented
+ with a precision of n bits."""
+ return max(1, int(round(int(n)/3.3219280948873626)-1))
+
+def dps_to_prec(n):
+ """Return the number of bits required to represent n decimals
+ accurately."""
+ return max(1, int(round((int(n)+1)*3.3219280948873626)))
+
+def repr_dps(n):
+ """Return the number of decimal digits required to represent
+ a number with n-bit precision so that it can be uniquely
+ reconstructed from the representation."""
+ dps = prec_to_dps(n)
+ if dps == 15:
+ return 17
+ return dps + 3
+
+#----------------------------------------------------------------------------#
+# Some commonly needed float values #
+#----------------------------------------------------------------------------#
+
+# Regular number format:
+# (-1)**sign * mantissa * 2**exponent, plus bitcount of mantissa
+fzero = (0, MPZ_ZERO, 0, 0)
+fnzero = (1, MPZ_ZERO, 0, 0)
+fone = (0, MPZ_ONE, 0, 1)
+fnone = (1, MPZ_ONE, 0, 1)
+ftwo = (0, MPZ_ONE, 1, 1)
+ften = (0, MPZ_FIVE, 1, 3)
+fhalf = (0, MPZ_ONE, -1, 1)
+
+# Arbitrary encoding for special numbers: zero mantissa, nonzero exponent
+fnan = (0, MPZ_ZERO, -123, -1)
+finf = (0, MPZ_ZERO, -456, -2)
+fninf = (1, MPZ_ZERO, -789, -3)
+
+# Was 1e1000; this is broken in Python 2.4
+math_float_inf = 1e300 * 1e300
+
+
+#----------------------------------------------------------------------------#
+# Rounding #
+#----------------------------------------------------------------------------#
+
+# This function can be used to round a mantissa generally. However,
+# we will try to do most rounding inline for efficiency.
+def round_int(x, n, rnd):
+ if rnd == round_nearest:
+ if x >= 0:
+ t = x >> (n-1)
+ if t & 1 and ((t & 2) or (x & h_mask[n<300][n])):
+ return (t>>1)+1
+ else:
+ return t>>1
+ else:
+ return -round_int(-x, n, rnd)
+ if rnd == round_floor:
+ return x >> n
+ if rnd == round_ceiling:
+ return -((-x) >> n)
+ if rnd == round_down:
+ if x >= 0:
+ return x >> n
+ return -((-x) >> n)
+ if rnd == round_up:
+ if x >= 0:
+ return -((-x) >> n)
+ return x >> n
+
+# These masks are used to pick out segments of numbers to determine
+# which direction to round when rounding to nearest.
+class h_mask_big:
+ def __getitem__(self, n):
+ return (MPZ_ONE<<(n-1))-1
+
+h_mask_small = [0]+[((MPZ_ONE<<(_-1))-1) for _ in range(1, 300)]
+h_mask = [h_mask_big(), h_mask_small]
+
+# The >> operator rounds to floor. shifts_down[rnd][sign]
+# tells whether this is the right direction to use, or if the
+# number should be negated before shifting
+shifts_down = {round_floor:(1,0), round_ceiling:(0,1),
+ round_down:(1,1), round_up:(0,0)}
+
+
+#----------------------------------------------------------------------------#
+# Normalization of raw mpfs #
+#----------------------------------------------------------------------------#
+
+# This function is called almost every time an mpf is created.
+# It has been optimized accordingly.
+
+def _normalize(sign, man, exp, bc, prec, rnd):
+ """
+ Create a raw mpf tuple with value (-1)**sign * man * 2**exp and
+ normalized mantissa. The mantissa is rounded in the specified
+ direction if its size exceeds the precision. Trailing zero bits
+ are also stripped from the mantissa to ensure that the
+ representation is canonical.
+
+ Conditions on the input:
+ * The input must represent a regular (finite) number
+ * The sign bit must be 0 or 1
+ * The mantissa must be positive
+ * The exponent must be an integer
+ * The bitcount must be exact
+
+ If these conditions are not met, use from_man_exp, mpf_pos, or any
+ of the conversion functions to create normalized raw mpf tuples.
+ """
+ if not man:
+ return fzero
+ # Cut mantissa down to size if larger than target precision
+ n = bc - prec
+ if n > 0:
+ if rnd == round_nearest:
+ t = man >> (n-1)
+ if t & 1 and ((t & 2) or (man & h_mask[n<300][n])):
+ man = (t>>1)+1
+ else:
+ man = t>>1
+ elif shifts_down[rnd][sign]:
+ man >>= n
+ else:
+ man = -((-man)>>n)
+ exp += n
+ bc = prec
+ # Strip trailing bits
+ if not man & 1:
+ t = trailtable[int(man & 255)]
+ if not t:
+ while not man & 255:
+ man >>= 8
+ exp += 8
+ bc -= 8
+ t = trailtable[int(man & 255)]
+ man >>= t
+ exp += t
+ bc -= t
+ # Bit count can be wrong if the input mantissa was 1 less than
+ # a power of 2 and got rounded up, thereby adding an extra bit.
+ # With trailing bits removed, all powers of two have mantissa 1,
+ # so this is easy to check for.
+ if man == 1:
+ bc = 1
+ return sign, man, exp, bc
+
+def _normalize1(sign, man, exp, bc, prec, rnd):
+ """same as normalize, but with the added condition that
+ man is odd or zero
+ """
+ if not man:
+ return fzero
+ if bc <= prec:
+ return sign, man, exp, bc
+ n = bc - prec
+ if rnd == round_nearest:
+ t = man >> (n-1)
+ if t & 1 and ((t & 2) or (man & h_mask[n<300][n])):
+ man = (t>>1)+1
+ else:
+ man = t>>1
+ elif shifts_down[rnd][sign]:
+ man >>= n
+ else:
+ man = -((-man)>>n)
+ exp += n
+ bc = prec
+ # Strip trailing bits
+ if not man & 1:
+ t = trailtable[int(man & 255)]
+ if not t:
+ while not man & 255:
+ man >>= 8
+ exp += 8
+ bc -= 8
+ t = trailtable[int(man & 255)]
+ man >>= t
+ exp += t
+ bc -= t
+ # Bit count can be wrong if the input mantissa was 1 less than
+ # a power of 2 and got rounded up, thereby adding an extra bit.
+ # With trailing bits removed, all powers of two have mantissa 1,
+ # so this is easy to check for.
+ if man == 1:
+ bc = 1
+ return sign, man, exp, bc
+
+try:
+ _exp_types = (int, long)
+except NameError:
+ _exp_types = (int,)
+
+def strict_normalize(sign, man, exp, bc, prec, rnd):
+ """Additional checks on the components of an mpf. Enable tests by setting
+ the environment variable MPMATH_STRICT to Y."""
+ assert type(man) == MPZ_TYPE
+ assert type(bc) in _exp_types
+ assert type(exp) in _exp_types
+ assert bc == bitcount(man)
+ return _normalize(sign, man, exp, bc, prec, rnd)
+
+def strict_normalize1(sign, man, exp, bc, prec, rnd):
+ """Additional checks on the components of an mpf. Enable tests by setting
+ the environment variable MPMATH_STRICT to Y."""
+ assert type(man) == MPZ_TYPE
+ assert type(bc) in _exp_types
+ assert type(exp) in _exp_types
+ assert bc == bitcount(man)
+ assert (not man) or (man & 1)
+ return _normalize1(sign, man, exp, bc, prec, rnd)
+
+if BACKEND == 'gmpy' and '_mpmath_normalize' in dir(gmpy):
+ _normalize = gmpy._mpmath_normalize
+ _normalize1 = gmpy._mpmath_normalize
+
+if BACKEND == 'sage':
+ _normalize = _normalize1 = sage_utils.normalize
+
+if STRICT:
+ normalize = strict_normalize
+ normalize1 = strict_normalize1
+else:
+ normalize = _normalize
+ normalize1 = _normalize1
+
+#----------------------------------------------------------------------------#
+# Conversion functions #
+#----------------------------------------------------------------------------#
+
+def from_man_exp(man, exp, prec=None, rnd=round_fast):
+ """Create raw mpf from (man, exp) pair. The mantissa may be signed.
+ If no precision is specified, the mantissa is stored exactly."""
+ man = MPZ(man)
+ sign = 0
+ if man < 0:
+ sign = 1
+ man = -man
+ if man < 1024:
+ bc = bctable[int(man)]
+ else:
+ bc = bitcount(man)
+ if not prec:
+ if not man:
+ return fzero
+ if not man & 1:
+ if man & 2:
+ return (sign, man >> 1, exp + 1, bc - 1)
+ t = trailtable[int(man & 255)]
+ if not t:
+ while not man & 255:
+ man >>= 8
+ exp += 8
+ bc -= 8
+ t = trailtable[int(man & 255)]
+ man >>= t
+ exp += t
+ bc -= t
+ return (sign, man, exp, bc)
+ return normalize(sign, man, exp, bc, prec, rnd)
+
+int_cache = dict((n, from_man_exp(n, 0)) for n in range(-10, 257))
+
+if BACKEND == 'gmpy' and '_mpmath_create' in dir(gmpy):
+ from_man_exp = gmpy._mpmath_create
+
+if BACKEND == 'sage':
+ from_man_exp = sage_utils.from_man_exp
+
+def from_int(n, prec=0, rnd=round_fast):
+ """Create a raw mpf from an integer. If no precision is specified,
+ the mantissa is stored exactly."""
+ if not prec:
+ if n in int_cache:
+ return int_cache[n]
+ return from_man_exp(n, 0, prec, rnd)
+
+def to_man_exp(s):
+ """Return (man, exp) of a raw mpf. Raise an error if inf/nan."""
+ sign, man, exp, bc = s
+ if (not man) and exp:
+ raise ValueError("mantissa and exponent are undefined for %s" % man)
+ return man, exp
+
+def to_int(s, rnd=None):
+ """Convert a raw mpf to the nearest int. Rounding is done down by
+ default (same as int(float) in Python), but can be changed. If the
+ input is inf/nan, an exception is raised."""
+ sign, man, exp, bc = s
+ if (not man) and exp:
+ raise ValueError("cannot convert inf or nan to int")
+ if exp >= 0:
+ if sign:
+ return (-man) << exp
+ return man << exp
+ # Make default rounding fast
+ if not rnd:
+ if sign:
+ return -(man >> (-exp))
+ else:
+ return man >> (-exp)
+ if sign:
+ return round_int(-man, -exp, rnd)
+ else:
+ return round_int(man, -exp, rnd)
+
+def mpf_round_int(s, rnd):
+ sign, man, exp, bc = s
+ if (not man) and exp:
+ return s
+ if exp >= 0:
+ return s
+ mag = exp+bc
+ if mag < 1:
+ if rnd == round_ceiling:
+ if sign: return fzero
+ else: return fone
+ elif rnd == round_floor:
+ if sign: return fnone
+ else: return fzero
+ elif rnd == round_nearest:
+ if mag < 0 or man == MPZ_ONE: return fzero
+ elif sign: return fnone
+ else: return fone
+ else:
+ raise NotImplementedError
+ return mpf_pos(s, min(bc, mag), rnd)
+
+def mpf_floor(s, prec=0, rnd=round_fast):
+ v = mpf_round_int(s, round_floor)
+ if prec:
+ v = mpf_pos(v, prec, rnd)
+ return v
+
+def mpf_ceil(s, prec=0, rnd=round_fast):
+ v = mpf_round_int(s, round_ceiling)
+ if prec:
+ v = mpf_pos(v, prec, rnd)
+ return v
+
+def mpf_nint(s, prec=0, rnd=round_fast):
+ v = mpf_round_int(s, round_nearest)
+ if prec:
+ v = mpf_pos(v, prec, rnd)
+ return v
+
+def mpf_frac(s, prec=0, rnd=round_fast):
+ return mpf_sub(s, mpf_floor(s), prec, rnd)
+
+def from_float(x, prec=53, rnd=round_fast):
+ """Create a raw mpf from a Python float, rounding if necessary.
+ If prec >= 53, the result is guaranteed to represent exactly the
+ same number as the input. If prec is not specified, use prec=53."""
+ # frexp only raises an exception for nan on some platforms
+ if x != x:
+ return fnan
+ # in Python2.5 math.frexp gives an exception for float infinity
+ # in Python2.6 it returns (float infinity, 0)
+ try:
+ m, e = math.frexp(x)
+ except:
+ if x == math_float_inf: return finf
+ if x == -math_float_inf: return fninf
+ return fnan
+ if x == math_float_inf: return finf
+ if x == -math_float_inf: return fninf
+ return from_man_exp(int(m*(1<<53)), e-53, prec, rnd)
+
+def from_npfloat(x, prec=113, rnd=round_fast):
+ """Create a raw mpf from a numpy float, rounding if necessary.
+ If prec >= 113, the result is guaranteed to represent exactly the
+ same number as the input. If prec is not specified, use prec=113."""
+ y = float(x)
+ if x == y: # ldexp overflows for float16
+ return from_float(y, prec, rnd)
+ import numpy as np
+ if np.isfinite(x):
+ m, e = np.frexp(x)
+ return from_man_exp(int(np.ldexp(m, 113)), int(e-113), prec, rnd)
+ if np.isposinf(x): return finf
+ if np.isneginf(x): return fninf
+ return fnan
+
+def from_Decimal(x, prec=None, rnd=round_fast):
+ """Create a raw mpf from a Decimal, rounding if necessary.
+ If prec is not specified, use the equivalent bit precision
+ of the number of significant digits in x."""
+ if x.is_nan(): return fnan
+ if x.is_infinite(): return fninf if x.is_signed() else finf
+ if prec is None:
+ prec = int(len(x.as_tuple()[1])*3.3219280948873626)
+ return from_str(str(x), prec, rnd)
+
+def to_float(s, strict=False, rnd=round_fast):
+ """
+ Convert a raw mpf to a Python float. The result is exact if the
+ bitcount of s is <= 53 and no underflow/overflow occurs.
+
+ If the number is too large or too small to represent as a regular
+ float, it will be converted to inf or 0.0. Setting strict=True
+ forces an OverflowError to be raised instead.
+
+ Warning: with a directed rounding mode, the correct nearest representable
+ floating-point number in the specified direction might not be computed
+ in case of overflow or (gradual) underflow.
+ """
+ sign, man, exp, bc = s
+ if not man:
+ if s == fzero: return 0.0
+ if s == finf: return math_float_inf
+ if s == fninf: return -math_float_inf
+ return math_float_inf/math_float_inf
+ if bc > 53:
+ sign, man, exp, bc = normalize1(sign, man, exp, bc, 53, rnd)
+ if sign:
+ man = -man
+ try:
+ return math.ldexp(man, exp)
+ except OverflowError:
+ if strict:
+ raise
+ # Overflow to infinity
+ if exp + bc > 0:
+ if sign:
+ return -math_float_inf
+ else:
+ return math_float_inf
+ # Underflow to zero
+ return 0.0
+
+def from_rational(p, q, prec, rnd=round_fast):
+ """Create a raw mpf from a rational number p/q, round if
+ necessary."""
+ return mpf_div(from_int(p), from_int(q), prec, rnd)
+
+def to_rational(s):
+ """Convert a raw mpf to a rational number. Return integers (p, q)
+ such that s = p/q exactly."""
+ sign, man, exp, bc = s
+ if sign:
+ man = -man
+ if bc == -1:
+ raise ValueError("cannot convert %s to a rational number" % man)
+ if exp >= 0:
+ return man * (1<= 0: return (-man) << offset
+ else: return (-man) >> (-offset)
+ else:
+ if offset >= 0: return man << offset
+ else: return man >> (-offset)
+
+
+##############################################################################
+##############################################################################
+
+#----------------------------------------------------------------------------#
+# Arithmetic operations, etc. #
+#----------------------------------------------------------------------------#
+
+def mpf_rand(prec):
+ """Return a raw mpf chosen randomly from [0, 1), with prec bits
+ in the mantissa."""
+ global getrandbits
+ if not getrandbits:
+ import random
+ getrandbits = random.getrandbits
+ return from_man_exp(getrandbits(prec), -prec, prec, round_floor)
+
+def mpf_eq(s, t):
+ """Test equality of two raw mpfs. This is simply tuple comparison
+ unless either number is nan, in which case the result is False."""
+ if not s[1] or not t[1]:
+ if s == fnan or t == fnan:
+ return False
+ return s == t
+
+def mpf_hash(s):
+ # Duplicate the new hash algorithm introduces in Python 3.2.
+ if sys.version_info >= (3, 2):
+ ssign, sman, sexp, sbc = s
+
+ # Handle special numbers
+ if not sman:
+ if s == fnan: return sys.hash_info.nan
+ if s == finf: return sys.hash_info.inf
+ if s == fninf: return -sys.hash_info.inf
+ h = sman % HASH_MODULUS
+ if sexp >= 0:
+ sexp = sexp % HASH_BITS
+ else:
+ sexp = HASH_BITS - 1 - ((-1 - sexp) % HASH_BITS)
+ h = (h << sexp) % HASH_MODULUS
+ if ssign: h = -h
+ if h == -1: h = -2
+ return int(h)
+ else:
+ try:
+ # Try to be compatible with hash values for floats and ints
+ return hash(to_float(s, strict=1))
+ except OverflowError:
+ # We must unfortunately sacrifice compatibility with ints here.
+ # We could do hash(man << exp) when the exponent is positive, but
+ # this would cause unreasonable inefficiency for large numbers.
+ return hash(s)
+
+def mpf_cmp(s, t):
+ """Compare the raw mpfs s and t. Return -1 if s < t, 0 if s == t,
+ and 1 if s > t. (Same convention as Python's cmp() function.)"""
+
+ # In principle, a comparison amounts to determining the sign of s-t.
+ # A full subtraction is relatively slow, however, so we first try to
+ # look at the components.
+ ssign, sman, sexp, sbc = s
+ tsign, tman, texp, tbc = t
+
+ # Handle zeros and special numbers
+ if not sman or not tman:
+ if s == fzero: return -mpf_sign(t)
+ if t == fzero: return mpf_sign(s)
+ if s == t: return 0
+ # Follow same convention as Python's cmp for float nan
+ if t == fnan: return 1
+ if s == finf: return 1
+ if t == fninf: return 1
+ return -1
+ # Different sides of zero
+ if ssign != tsign:
+ if not ssign: return 1
+ return -1
+ # This reduces to direct integer comparison
+ if sexp == texp:
+ if sman == tman:
+ return 0
+ if sman > tman:
+ if ssign: return -1
+ else: return 1
+ else:
+ if ssign: return 1
+ else: return -1
+ # Check position of the highest set bit in each number. If
+ # different, there is certainly an inequality.
+ a = sbc + sexp
+ b = tbc + texp
+ if ssign:
+ if a < b: return 1
+ if a > b: return -1
+ else:
+ if a < b: return -1
+ if a > b: return 1
+
+ # Both numbers have the same highest bit. Subtract to find
+ # how the lower bits compare.
+ delta = mpf_sub(s, t, 5, round_floor)
+ if delta[0]:
+ return -1
+ return 1
+
+def mpf_lt(s, t):
+ if s == fnan or t == fnan:
+ return False
+ return mpf_cmp(s, t) < 0
+
+def mpf_le(s, t):
+ if s == fnan or t == fnan:
+ return False
+ return mpf_cmp(s, t) <= 0
+
+def mpf_gt(s, t):
+ if s == fnan or t == fnan:
+ return False
+ return mpf_cmp(s, t) > 0
+
+def mpf_ge(s, t):
+ if s == fnan or t == fnan:
+ return False
+ return mpf_cmp(s, t) >= 0
+
+def mpf_min_max(seq):
+ min = max = seq[0]
+ for x in seq[1:]:
+ if mpf_lt(x, min): min = x
+ if mpf_gt(x, max): max = x
+ return min, max
+
+def mpf_pos(s, prec=0, rnd=round_fast):
+ """Calculate 0+s for a raw mpf (i.e., just round s to the specified
+ precision)."""
+ if prec:
+ sign, man, exp, bc = s
+ if (not man) and exp:
+ return s
+ return normalize1(sign, man, exp, bc, prec, rnd)
+ return s
+
+def mpf_neg(s, prec=None, rnd=round_fast):
+ """Negate a raw mpf (return -s), rounding the result to the
+ specified precision. The prec argument can be omitted to do the
+ operation exactly."""
+ sign, man, exp, bc = s
+ if not man:
+ if exp:
+ if s == finf: return fninf
+ if s == fninf: return finf
+ return s
+ if not prec:
+ return (1-sign, man, exp, bc)
+ return normalize1(1-sign, man, exp, bc, prec, rnd)
+
+def mpf_abs(s, prec=None, rnd=round_fast):
+ """Return abs(s) of the raw mpf s, rounded to the specified
+ precision. The prec argument can be omitted to generate an
+ exact result."""
+ sign, man, exp, bc = s
+ if (not man) and exp:
+ if s == fninf:
+ return finf
+ return s
+ if not prec:
+ if sign:
+ return (0, man, exp, bc)
+ return s
+ return normalize1(0, man, exp, bc, prec, rnd)
+
+def mpf_sign(s):
+ """Return -1, 0, or 1 (as a Python int, not a raw mpf) depending on
+ whether s is negative, zero, or positive. (Nan is taken to give 0.)"""
+ sign, man, exp, bc = s
+ if not man:
+ if s == finf: return 1
+ if s == fninf: return -1
+ return 0
+ return (-1) ** sign
+
+def mpf_add(s, t, prec=0, rnd=round_fast, _sub=0):
+ """
+ Add the two raw mpf values s and t.
+
+ With prec=0, no rounding is performed. Note that this can
+ produce a very large mantissa (potentially too large to fit
+ in memory) if exponents are far apart.
+ """
+ ssign, sman, sexp, sbc = s
+ tsign, tman, texp, tbc = t
+ tsign ^= _sub
+ # Standard case: two nonzero, regular numbers
+ if sman and tman:
+ offset = sexp - texp
+ if offset:
+ if offset > 0:
+ # Outside precision range; only need to perturb
+ if offset > 100 and prec:
+ delta = sbc + sexp - tbc - texp
+ if delta > prec + 4:
+ offset = prec + 4
+ sman <<= offset
+ if tsign == ssign: sman += 1
+ else: sman -= 1
+ return normalize1(ssign, sman, sexp-offset,
+ bitcount(sman), prec, rnd)
+ # Add
+ if ssign == tsign:
+ man = tman + (sman << offset)
+ # Subtract
+ else:
+ if ssign: man = tman - (sman << offset)
+ else: man = (sman << offset) - tman
+ if man >= 0:
+ ssign = 0
+ else:
+ man = -man
+ ssign = 1
+ bc = bitcount(man)
+ return normalize1(ssign, man, texp, bc, prec or bc, rnd)
+ elif offset < 0:
+ # Outside precision range; only need to perturb
+ if offset < -100 and prec:
+ delta = tbc + texp - sbc - sexp
+ if delta > prec + 4:
+ offset = prec + 4
+ tman <<= offset
+ if ssign == tsign: tman += 1
+ else: tman -= 1
+ return normalize1(tsign, tman, texp-offset,
+ bitcount(tman), prec, rnd)
+ # Add
+ if ssign == tsign:
+ man = sman + (tman << -offset)
+ # Subtract
+ else:
+ if tsign: man = sman - (tman << -offset)
+ else: man = (tman << -offset) - sman
+ if man >= 0:
+ ssign = 0
+ else:
+ man = -man
+ ssign = 1
+ bc = bitcount(man)
+ return normalize1(ssign, man, sexp, bc, prec or bc, rnd)
+ # Equal exponents; no shifting necessary
+ if ssign == tsign:
+ man = tman + sman
+ else:
+ if ssign: man = tman - sman
+ else: man = sman - tman
+ if man >= 0:
+ ssign = 0
+ else:
+ man = -man
+ ssign = 1
+ bc = bitcount(man)
+ return normalize(ssign, man, texp, bc, prec or bc, rnd)
+ # Handle zeros and special numbers
+ if _sub:
+ t = mpf_neg(t)
+ if not sman:
+ if sexp:
+ if s == t or tman or not texp:
+ return s
+ return fnan
+ if tman:
+ return normalize1(tsign, tman, texp, tbc, prec or tbc, rnd)
+ return t
+ if texp:
+ return t
+ if sman:
+ return normalize1(ssign, sman, sexp, sbc, prec or sbc, rnd)
+ return s
+
+def mpf_sub(s, t, prec=0, rnd=round_fast):
+ """Return the difference of two raw mpfs, s-t. This function is
+ simply a wrapper of mpf_add that changes the sign of t."""
+ return mpf_add(s, t, prec, rnd, 1)
+
+def mpf_sum(xs, prec=0, rnd=round_fast, absolute=False):
+ """
+ Sum a list of mpf values efficiently and accurately
+ (typically no temporary roundoff occurs). If prec=0,
+ the final result will not be rounded either.
+
+ There may be roundoff error or cancellation if extremely
+ large exponent differences occur.
+
+ With absolute=True, sums the absolute values.
+ """
+ man = 0
+ exp = 0
+ max_extra_prec = prec*2 or 1000000 # XXX
+ special = None
+ for x in xs:
+ xsign, xman, xexp, xbc = x
+ if xman:
+ if xsign and not absolute:
+ xman = -xman
+ delta = xexp - exp
+ if xexp >= exp:
+ # x much larger than existing sum?
+ # first: quick test
+ if (delta > max_extra_prec) and \
+ ((not man) or delta-bitcount(abs(man)) > max_extra_prec):
+ man = xman
+ exp = xexp
+ else:
+ man += (xman << delta)
+ else:
+ delta = -delta
+ # x much smaller than existing sum?
+ if delta-xbc > max_extra_prec:
+ if not man:
+ man, exp = xman, xexp
+ else:
+ man = (man << delta) + xman
+ exp = xexp
+ elif xexp:
+ if absolute:
+ x = mpf_abs(x)
+ special = mpf_add(special or fzero, x, 1)
+ # Will be inf or nan
+ if special:
+ return special
+ return from_man_exp(man, exp, prec, rnd)
+
+def gmpy_mpf_mul(s, t, prec=0, rnd=round_fast):
+ """Multiply two raw mpfs"""
+ ssign, sman, sexp, sbc = s
+ tsign, tman, texp, tbc = t
+ sign = ssign ^ tsign
+ man = sman*tman
+ if man:
+ bc = bitcount(man)
+ if prec:
+ return normalize1(sign, man, sexp+texp, bc, prec, rnd)
+ else:
+ return (sign, man, sexp+texp, bc)
+ s_special = (not sman) and sexp
+ t_special = (not tman) and texp
+ if not s_special and not t_special:
+ return fzero
+ if fnan in (s, t): return fnan
+ if (not tman) and texp: s, t = t, s
+ if t == fzero: return fnan
+ return {1:finf, -1:fninf}[mpf_sign(s) * mpf_sign(t)]
+
+def gmpy_mpf_mul_int(s, n, prec, rnd=round_fast):
+ """Multiply by a Python integer."""
+ sign, man, exp, bc = s
+ if not man:
+ return mpf_mul(s, from_int(n), prec, rnd)
+ if not n:
+ return fzero
+ if n < 0:
+ sign ^= 1
+ n = -n
+ man *= n
+ return normalize(sign, man, exp, bitcount(man), prec, rnd)
+
+def python_mpf_mul(s, t, prec=0, rnd=round_fast):
+ """Multiply two raw mpfs"""
+ ssign, sman, sexp, sbc = s
+ tsign, tman, texp, tbc = t
+ sign = ssign ^ tsign
+ man = sman*tman
+ if man:
+ bc = sbc + tbc - 1
+ bc += int(man>>bc)
+ if prec:
+ return normalize1(sign, man, sexp+texp, bc, prec, rnd)
+ else:
+ return (sign, man, sexp+texp, bc)
+ s_special = (not sman) and sexp
+ t_special = (not tman) and texp
+ if not s_special and not t_special:
+ return fzero
+ if fnan in (s, t): return fnan
+ if (not tman) and texp: s, t = t, s
+ if t == fzero: return fnan
+ return {1:finf, -1:fninf}[mpf_sign(s) * mpf_sign(t)]
+
+def python_mpf_mul_int(s, n, prec, rnd=round_fast):
+ """Multiply by a Python integer."""
+ sign, man, exp, bc = s
+ if not man:
+ return mpf_mul(s, from_int(n), prec, rnd)
+ if not n:
+ return fzero
+ if n < 0:
+ sign ^= 1
+ n = -n
+ man *= n
+ # Generally n will be small
+ if n < 1024:
+ bc += bctable[int(n)] - 1
+ else:
+ bc += bitcount(n) - 1
+ bc += int(man>>bc)
+ return normalize(sign, man, exp, bc, prec, rnd)
+
+
+if BACKEND == 'gmpy':
+ mpf_mul = gmpy_mpf_mul
+ mpf_mul_int = gmpy_mpf_mul_int
+else:
+ mpf_mul = python_mpf_mul
+ mpf_mul_int = python_mpf_mul_int
+
+def mpf_shift(s, n):
+ """Quickly multiply the raw mpf s by 2**n without rounding."""
+ sign, man, exp, bc = s
+ if not man:
+ return s
+ return sign, man, exp+n, bc
+
+def mpf_frexp(x):
+ """Convert x = y*2**n to (y, n) with abs(y) in [0.5, 1) if nonzero"""
+ sign, man, exp, bc = x
+ if not man:
+ if x == fzero:
+ return (fzero, 0)
+ else:
+ raise ValueError
+ return mpf_shift(x, -bc-exp), bc+exp
+
+def mpf_div(s, t, prec, rnd=round_fast):
+ """Floating-point division"""
+ ssign, sman, sexp, sbc = s
+ tsign, tman, texp, tbc = t
+ if not sman or not tman:
+ if s == fzero:
+ if t == fzero: raise ZeroDivisionError
+ if t == fnan: return fnan
+ return fzero
+ if t == fzero:
+ raise ZeroDivisionError
+ s_special = (not sman) and sexp
+ t_special = (not tman) and texp
+ if s_special and t_special:
+ return fnan
+ if s == fnan or t == fnan:
+ return fnan
+ if not t_special:
+ if t == fzero:
+ return fnan
+ return {1:finf, -1:fninf}[mpf_sign(s) * mpf_sign(t)]
+ return fzero
+ sign = ssign ^ tsign
+ if tman == 1:
+ return normalize1(sign, sman, sexp-texp, sbc, prec, rnd)
+ # Same strategy as for addition: if there is a remainder, perturb
+ # the result a few bits outside the precision range before rounding
+ extra = prec - sbc + tbc + 5
+ if extra < 5:
+ extra = 5
+ quot, rem = divmod(sman< sexp+sbc:
+ return s
+ # Another important special case: this allows us to do e.g. x % 1.0
+ # to find the fractional part of x, and it will work when x is huge.
+ if tman == 1 and sexp > texp+tbc:
+ return fzero
+ base = min(sexp, texp)
+ sman = (-1)**ssign * sman
+ tman = (-1)**tsign * tman
+ man = (sman << (sexp-base)) % (tman << (texp-base))
+ if man >= 0:
+ sign = 0
+ else:
+ man = -man
+ sign = 1
+ return normalize(sign, man, base, bitcount(man), prec, rnd)
+
+reciprocal_rnd = {
+ round_down : round_up,
+ round_up : round_down,
+ round_floor : round_ceiling,
+ round_ceiling : round_floor,
+ round_nearest : round_nearest
+}
+
+negative_rnd = {
+ round_down : round_down,
+ round_up : round_up,
+ round_floor : round_ceiling,
+ round_ceiling : round_floor,
+ round_nearest : round_nearest
+}
+
+def mpf_pow_int(s, n, prec, rnd=round_fast):
+ """Compute s**n, where s is a raw mpf and n is a Python integer."""
+ sign, man, exp, bc = s
+
+ if (not man) and exp:
+ if s == finf:
+ if n > 0: return s
+ if n == 0: return fnan
+ return fzero
+ if s == fninf:
+ if n > 0: return [finf, fninf][n & 1]
+ if n == 0: return fnan
+ return fzero
+ return fnan
+
+ n = int(n)
+ if n == 0: return fone
+ if n == 1: return mpf_pos(s, prec, rnd)
+ if n == 2:
+ _, man, exp, bc = s
+ if not man:
+ return fzero
+ man = man*man
+ if man == 1:
+ return (0, MPZ_ONE, exp+exp, 1)
+ bc = bc + bc - 2
+ bc += bctable[int(man>>bc)]
+ return normalize1(0, man, exp+exp, bc, prec, rnd)
+ if n == -1: return mpf_div(fone, s, prec, rnd)
+ if n < 0:
+ inverse = mpf_pow_int(s, -n, prec+5, reciprocal_rnd[rnd])
+ return mpf_div(fone, inverse, prec, rnd)
+
+ result_sign = sign & n
+
+ # Use exact integer power when the exact mantissa is small
+ if man == 1:
+ return (result_sign, MPZ_ONE, exp*n, 1)
+ if bc*n < 1000:
+ man **= n
+ return normalize1(result_sign, man, exp*n, bitcount(man), prec, rnd)
+
+ # Use directed rounding all the way through to maintain rigorous
+ # bounds for interval arithmetic
+ rounds_down = (rnd == round_nearest) or \
+ shifts_down[rnd][result_sign]
+
+ # Now we perform binary exponentiation. Need to estimate precision
+ # to avoid rounding errors from temporary operations. Roughly log_2(n)
+ # operations are performed.
+ workprec = prec + 4*bitcount(n) + 4
+ _, pm, pe, pbc = fone
+ while 1:
+ if n & 1:
+ pm = pm*man
+ pe = pe+exp
+ pbc += bc - 2
+ pbc = pbc + bctable[int(pm >> pbc)]
+ if pbc > workprec:
+ if rounds_down:
+ pm = pm >> (pbc-workprec)
+ else:
+ pm = -((-pm) >> (pbc-workprec))
+ pe += pbc - workprec
+ pbc = workprec
+ n -= 1
+ if not n:
+ break
+ man = man*man
+ exp = exp+exp
+ bc = bc + bc - 2
+ bc = bc + bctable[int(man >> bc)]
+ if bc > workprec:
+ if rounds_down:
+ man = man >> (bc-workprec)
+ else:
+ man = -((-man) >> (bc-workprec))
+ exp += bc - workprec
+ bc = workprec
+ n = n // 2
+
+ return normalize(result_sign, pm, pe, pbc, prec, rnd)
+
+
+def mpf_perturb(x, eps_sign, prec, rnd):
+ """
+ For nonzero x, calculate x + eps with directed rounding, where
+ eps < prec relatively and eps has the given sign (0 for
+ positive, 1 for negative).
+
+ With rounding to nearest, this is taken to simply normalize
+ x to the given precision.
+ """
+ if rnd == round_nearest:
+ return mpf_pos(x, prec, rnd)
+ sign, man, exp, bc = x
+ eps = (eps_sign, MPZ_ONE, exp+bc-prec-1, 1)
+ if sign:
+ away = (rnd in (round_down, round_ceiling)) ^ eps_sign
+ else:
+ away = (rnd in (round_up, round_ceiling)) ^ eps_sign
+ if away:
+ return mpf_add(x, eps, prec, rnd)
+ else:
+ return mpf_pos(x, prec, rnd)
+
+
+#----------------------------------------------------------------------------#
+# Radix conversion #
+#----------------------------------------------------------------------------#
+
+def to_digits_exp(s, dps):
+ """Helper function for representing the floating-point number s as
+ a decimal with dps digits. Returns (sign, string, exponent) where
+ sign is '' or '-', string is the digit string, and exponent is
+ the decimal exponent as an int.
+
+ If inexact, the decimal representation is rounded toward zero."""
+
+ # Extract sign first so it doesn't mess up the string digit count
+ if s[0]:
+ sign = '-'
+ s = mpf_neg(s)
+ else:
+ sign = ''
+ _sign, man, exp, bc = s
+
+ if not man:
+ return '', '0', 0
+
+ bitprec = int(dps * math.log(10,2)) + 10
+
+ # Cut down to size
+ # TODO: account for precision when doing this
+ exp_from_1 = exp + bc
+ if abs(exp_from_1) > 3500:
+ from .libelefun import mpf_ln2, mpf_ln10
+ # Set b = int(exp * log(2)/log(10))
+ # If exp is huge, we must use high-precision arithmetic to
+ # find the nearest power of ten
+ expprec = bitcount(abs(exp)) + 5
+ tmp = from_int(exp)
+ tmp = mpf_mul(tmp, mpf_ln2(expprec))
+ tmp = mpf_div(tmp, mpf_ln10(expprec), expprec)
+ b = to_int(tmp)
+ s = mpf_div(s, mpf_pow_int(ften, b, bitprec), bitprec)
+ _sign, man, exp, bc = s
+ exponent = b
+ else:
+ exponent = 0
+
+ # First, calculate mantissa digits by converting to a binary
+ # fixed-point number and then converting that number to
+ # a decimal fixed-point number.
+ fixprec = max(bitprec - exp - bc, 0)
+ fixdps = int(fixprec / math.log(10,2) + 0.5)
+ sf = to_fixed(s, fixprec)
+ sd = bin_to_radix(sf, fixprec, 10, fixdps)
+ digits = numeral(sd, base=10, size=dps)
+
+ exponent += len(digits) - fixdps - 1
+ return sign, digits, exponent
+
+def to_str(s, dps, strip_zeros=True, min_fixed=None, max_fixed=None,
+ show_zero_exponent=False):
+ """
+ Convert a raw mpf to a decimal floating-point literal with at
+ most `dps` decimal digits in the mantissa (not counting extra zeros
+ that may be inserted for visual purposes).
+
+ The number will be printed in fixed-point format if the position
+ of the leading digit is strictly between min_fixed
+ (default = min(-dps/3,-5)) and max_fixed (default = dps).
+
+ To force fixed-point format always, set min_fixed = -inf,
+ max_fixed = +inf. To force floating-point format, set
+ min_fixed >= max_fixed.
+
+ The literal is formatted so that it can be parsed back to a number
+ by to_str, float() or Decimal().
+ """
+
+ # Special numbers
+ if not s[1]:
+ if s == fzero:
+ if dps: t = '0.0'
+ else: t = '.0'
+ if show_zero_exponent:
+ t += 'e+0'
+ return t
+ if s == finf: return '+inf'
+ if s == fninf: return '-inf'
+ if s == fnan: return 'nan'
+ raise ValueError
+
+ if min_fixed is None: min_fixed = min(-(dps//3), -5)
+ if max_fixed is None: max_fixed = dps
+
+ # to_digits_exp rounds to floor.
+ # This sometimes kills some instances of "...00001"
+ sign, digits, exponent = to_digits_exp(s, dps+3)
+
+ # No digits: show only .0; round exponent to nearest
+ if not dps:
+ if digits[0] in '56789':
+ exponent += 1
+ digits = ".0"
+
+ else:
+ # Rounding up kills some instances of "...99999"
+ if len(digits) > dps and digits[dps] in '56789':
+ digits = digits[:dps]
+ i = dps - 1
+ while i >= 0 and digits[i] == '9':
+ i -= 1
+ if i >= 0:
+ digits = digits[:i] + str(int(digits[i]) + 1) + '0' * (dps - i - 1)
+ else:
+ digits = '1' + '0' * (dps - 1)
+ exponent += 1
+ else:
+ digits = digits[:dps]
+
+ # Prettify numbers close to unit magnitude
+ if min_fixed < exponent < max_fixed:
+ if exponent < 0:
+ digits = ("0"*int(-exponent)) + digits
+ split = 1
+ else:
+ split = exponent + 1
+ if split > dps:
+ digits += "0"*(split-dps)
+ exponent = 0
+ else:
+ split = 1
+
+ digits = (digits[:split] + "." + digits[split:])
+
+ if strip_zeros:
+ # Clean up trailing zeros
+ digits = digits.rstrip('0')
+ if digits[-1] == ".":
+ digits += "0"
+
+ if exponent == 0 and dps and not show_zero_exponent: return sign + digits
+ if exponent >= 0: return sign + digits + "e+" + str(exponent)
+ if exponent < 0: return sign + digits + "e" + str(exponent)
+
+def str_to_man_exp(x, base=10):
+ """Helper function for from_str."""
+ x = x.lower().rstrip('l')
+ # Verify that the input is a valid float literal
+ float(x)
+ # Split into mantissa, exponent
+ parts = x.split('e')
+ if len(parts) == 1:
+ exp = 0
+ else: # == 2
+ x = parts[0]
+ exp = int(parts[1])
+ # Look for radix point in mantissa
+ parts = x.split('.')
+ if len(parts) == 2:
+ a, b = parts[0], parts[1].rstrip('0')
+ exp -= len(b)
+ x = a + b
+ x = MPZ(int(x, base))
+ return x, exp
+
+special_str = {'inf':finf, '+inf':finf, '-inf':fninf, 'nan':fnan}
+
+def from_str(x, prec, rnd=round_fast):
+ """Create a raw mpf from a decimal literal, rounding in the
+ specified direction if the input number cannot be represented
+ exactly as a binary floating-point number with the given number of
+ bits. The literal syntax accepted is the same as for Python
+ floats.
+
+ TODO: the rounding does not work properly for large exponents.
+ """
+ x = x.lower().strip()
+ if x in special_str:
+ return special_str[x]
+
+ if '/' in x:
+ p, q = x.split('/')
+ p, q = p.rstrip('l'), q.rstrip('l')
+ return from_rational(int(p), int(q), prec, rnd)
+
+ man, exp = str_to_man_exp(x, base=10)
+
+ # XXX: appropriate cutoffs & track direction
+ # note no factors of 5
+ if abs(exp) > 400:
+ s = from_int(man, prec+10)
+ s = mpf_mul(s, mpf_pow_int(ften, exp, prec+10), prec, rnd)
+ else:
+ if exp >= 0:
+ s = from_int(man * 10**exp, prec, rnd)
+ else:
+ s = from_rational(man, 10**-exp, prec, rnd)
+ return s
+
+# Binary string conversion. These are currently mainly used for debugging
+# and could use some improvement in the future
+
+def from_bstr(x):
+ man, exp = str_to_man_exp(x, base=2)
+ man = MPZ(man)
+ sign = 0
+ if man < 0:
+ man = -man
+ sign = 1
+ bc = bitcount(man)
+ return normalize(sign, man, exp, bc, bc, round_floor)
+
+def to_bstr(x):
+ sign, man, exp, bc = x
+ return ['','-'][sign] + numeral(man, size=bitcount(man), base=2) + ("e%i" % exp)
+
+
+#----------------------------------------------------------------------------#
+# Square roots #
+#----------------------------------------------------------------------------#
+
+
+def mpf_sqrt(s, prec, rnd=round_fast):
+ """
+ Compute the square root of a nonnegative mpf value. The
+ result is correctly rounded.
+ """
+ sign, man, exp, bc = s
+ if sign:
+ raise ComplexResult("square root of a negative number")
+ if not man:
+ return s
+ if exp & 1:
+ exp -= 1
+ man <<= 1
+ bc += 1
+ elif man == 1:
+ return normalize1(sign, man, exp//2, bc, prec, rnd)
+ shift = max(4, 2*prec-bc+4)
+ shift += shift & 1
+ if rnd in 'fd':
+ man = isqrt(man<= 0:
+ a = mpf_pos(sa, prec, round_floor)
+ b = mpf_pos(sb, prec, round_ceiling)
+ # Upper point nonnegative?
+ elif sbs >= 0:
+ a = fzero
+ negsa = mpf_neg(sa)
+ if mpf_lt(negsa, sb):
+ b = mpf_pos(sb, prec, round_ceiling)
+ else:
+ b = mpf_pos(negsa, prec, round_ceiling)
+ # Both negative?
+ else:
+ a = mpf_neg(sb, prec, round_floor)
+ b = mpf_neg(sa, prec, round_ceiling)
+ return a, b
+
+# TODO: optimize
+def mpi_mul_mpf(s, t, prec):
+ return mpi_mul(s, (t, t), prec)
+
+def mpi_div_mpf(s, t, prec):
+ return mpi_div(s, (t, t), prec)
+
+def mpi_mul(s, t, prec=0):
+ sa, sb = s
+ ta, tb = t
+ sas = mpf_sign(sa)
+ sbs = mpf_sign(sb)
+ tas = mpf_sign(ta)
+ tbs = mpf_sign(tb)
+ if sas == sbs == 0:
+ # Should maybe be undefined
+ if ta == fninf or tb == finf:
+ return fninf, finf
+ return fzero, fzero
+ if tas == tbs == 0:
+ # Should maybe be undefined
+ if sa == fninf or sb == finf:
+ return fninf, finf
+ return fzero, fzero
+ if sas >= 0:
+ # positive * positive
+ if tas >= 0:
+ a = mpf_mul(sa, ta, prec, round_floor)
+ b = mpf_mul(sb, tb, prec, round_ceiling)
+ if a == fnan: a = fzero
+ if b == fnan: b = finf
+ # positive * negative
+ elif tbs <= 0:
+ a = mpf_mul(sb, ta, prec, round_floor)
+ b = mpf_mul(sa, tb, prec, round_ceiling)
+ if a == fnan: a = fninf
+ if b == fnan: b = fzero
+ # positive * both signs
+ else:
+ a = mpf_mul(sb, ta, prec, round_floor)
+ b = mpf_mul(sb, tb, prec, round_ceiling)
+ if a == fnan: a = fninf
+ if b == fnan: b = finf
+ elif sbs <= 0:
+ # negative * positive
+ if tas >= 0:
+ a = mpf_mul(sa, tb, prec, round_floor)
+ b = mpf_mul(sb, ta, prec, round_ceiling)
+ if a == fnan: a = fninf
+ if b == fnan: b = fzero
+ # negative * negative
+ elif tbs <= 0:
+ a = mpf_mul(sb, tb, prec, round_floor)
+ b = mpf_mul(sa, ta, prec, round_ceiling)
+ if a == fnan: a = fzero
+ if b == fnan: b = finf
+ # negative * both signs
+ else:
+ a = mpf_mul(sa, tb, prec, round_floor)
+ b = mpf_mul(sa, ta, prec, round_ceiling)
+ if a == fnan: a = fninf
+ if b == fnan: b = finf
+ else:
+ # General case: perform all cross-multiplications and compare
+ # Since the multiplications can be done exactly, we need only
+ # do 4 (instead of 8: two for each rounding mode)
+ cases = [mpf_mul(sa, ta), mpf_mul(sa, tb), mpf_mul(sb, ta), mpf_mul(sb, tb)]
+ if fnan in cases:
+ a, b = (fninf, finf)
+ else:
+ a, b = mpf_min_max(cases)
+ a = mpf_pos(a, prec, round_floor)
+ b = mpf_pos(b, prec, round_ceiling)
+ return a, b
+
+def mpi_square(s, prec=0):
+ sa, sb = s
+ if mpf_ge(sa, fzero):
+ a = mpf_mul(sa, sa, prec, round_floor)
+ b = mpf_mul(sb, sb, prec, round_ceiling)
+ elif mpf_le(sb, fzero):
+ a = mpf_mul(sb, sb, prec, round_floor)
+ b = mpf_mul(sa, sa, prec, round_ceiling)
+ else:
+ sa = mpf_neg(sa)
+ sa, sb = mpf_min_max([sa, sb])
+ a = fzero
+ b = mpf_mul(sb, sb, prec, round_ceiling)
+ return a, b
+
+def mpi_div(s, t, prec):
+ sa, sb = s
+ ta, tb = t
+ sas = mpf_sign(sa)
+ sbs = mpf_sign(sb)
+ tas = mpf_sign(ta)
+ tbs = mpf_sign(tb)
+ # 0 / X
+ if sas == sbs == 0:
+ # 0 /
+ if (tas < 0 and tbs > 0) or (tas == 0 or tbs == 0):
+ return fninf, finf
+ return fzero, fzero
+ # Denominator contains both negative and positive numbers;
+ # this should properly be a multi-interval, but the closest
+ # match is the entire (extended) real line
+ if tas < 0 and tbs > 0:
+ return fninf, finf
+ # Assume denominator to be nonnegative
+ if tas < 0:
+ return mpi_div(mpi_neg(s), mpi_neg(t), prec)
+ # Division by zero
+ # XXX: make sure all results make sense
+ if tas == 0:
+ # Numerator contains both signs?
+ if sas < 0 and sbs > 0:
+ return fninf, finf
+ if tas == tbs:
+ return fninf, finf
+ # Numerator positive?
+ if sas >= 0:
+ a = mpf_div(sa, tb, prec, round_floor)
+ b = finf
+ if sbs <= 0:
+ a = fninf
+ b = mpf_div(sb, tb, prec, round_ceiling)
+ # Division with positive denominator
+ # We still have to handle nans resulting from inf/0 or inf/inf
+ else:
+ # Nonnegative numerator
+ if sas >= 0:
+ a = mpf_div(sa, tb, prec, round_floor)
+ b = mpf_div(sb, ta, prec, round_ceiling)
+ if a == fnan: a = fzero
+ if b == fnan: b = finf
+ # Nonpositive numerator
+ elif sbs <= 0:
+ a = mpf_div(sa, ta, prec, round_floor)
+ b = mpf_div(sb, tb, prec, round_ceiling)
+ if a == fnan: a = fninf
+ if b == fnan: b = fzero
+ # Numerator contains both signs?
+ else:
+ a = mpf_div(sa, ta, prec, round_floor)
+ b = mpf_div(sb, ta, prec, round_ceiling)
+ if a == fnan: a = fninf
+ if b == fnan: b = finf
+ return a, b
+
+def mpi_pi(prec):
+ a = mpf_pi(prec, round_floor)
+ b = mpf_pi(prec, round_ceiling)
+ return a, b
+
+def mpi_exp(s, prec):
+ sa, sb = s
+ # exp is monotonic
+ a = mpf_exp(sa, prec, round_floor)
+ b = mpf_exp(sb, prec, round_ceiling)
+ return a, b
+
+def mpi_log(s, prec):
+ sa, sb = s
+ # log is monotonic
+ a = mpf_log(sa, prec, round_floor)
+ b = mpf_log(sb, prec, round_ceiling)
+ return a, b
+
+def mpi_sqrt(s, prec):
+ sa, sb = s
+ # sqrt is monotonic
+ a = mpf_sqrt(sa, prec, round_floor)
+ b = mpf_sqrt(sb, prec, round_ceiling)
+ return a, b
+
+def mpi_atan(s, prec):
+ sa, sb = s
+ a = mpf_atan(sa, prec, round_floor)
+ b = mpf_atan(sb, prec, round_ceiling)
+ return a, b
+
+def mpi_pow_int(s, n, prec):
+ sa, sb = s
+ if n < 0:
+ return mpi_div((fone, fone), mpi_pow_int(s, -n, prec+20), prec)
+ if n == 0:
+ return (fone, fone)
+ if n == 1:
+ return s
+ if n == 2:
+ return mpi_square(s, prec)
+ # Odd -- signs are preserved
+ if n & 1:
+ a = mpf_pow_int(sa, n, prec, round_floor)
+ b = mpf_pow_int(sb, n, prec, round_ceiling)
+ # Even -- important to ensure positivity
+ else:
+ sas = mpf_sign(sa)
+ sbs = mpf_sign(sb)
+ # Nonnegative?
+ if sas >= 0:
+ a = mpf_pow_int(sa, n, prec, round_floor)
+ b = mpf_pow_int(sb, n, prec, round_ceiling)
+ # Nonpositive?
+ elif sbs <= 0:
+ a = mpf_pow_int(sb, n, prec, round_floor)
+ b = mpf_pow_int(sa, n, prec, round_ceiling)
+ # Mixed signs?
+ else:
+ a = fzero
+ # max(-a,b)**n
+ sa = mpf_neg(sa)
+ if mpf_ge(sa, sb):
+ b = mpf_pow_int(sa, n, prec, round_ceiling)
+ else:
+ b = mpf_pow_int(sb, n, prec, round_ceiling)
+ return a, b
+
+def mpi_pow(s, t, prec):
+ ta, tb = t
+ if ta == tb and ta not in (finf, fninf):
+ if ta == from_int(to_int(ta)):
+ return mpi_pow_int(s, to_int(ta), prec)
+ if ta == fhalf:
+ return mpi_sqrt(s, prec)
+ u = mpi_log(s, prec + 20)
+ v = mpi_mul(u, t, prec + 20)
+ return mpi_exp(v, prec)
+
+def MIN(x, y):
+ if mpf_le(x, y):
+ return x
+ return y
+
+def MAX(x, y):
+ if mpf_ge(x, y):
+ return x
+ return y
+
+def cos_sin_quadrant(x, wp):
+ sign, man, exp, bc = x
+ if x == fzero:
+ return fone, fzero, 0
+ # TODO: combine evaluation code to avoid duplicate modulo
+ c, s = mpf_cos_sin(x, wp)
+ t, n, wp_ = mod_pi2(man, exp, exp+bc, 15)
+ if sign:
+ n = -1-n
+ return c, s, n
+
+def mpi_cos_sin(x, prec):
+ a, b = x
+ if a == b == fzero:
+ return (fone, fone), (fzero, fzero)
+ # Guaranteed to contain both -1 and 1
+ if (finf in x) or (fninf in x):
+ return (fnone, fone), (fnone, fone)
+ wp = prec + 20
+ ca, sa, na = cos_sin_quadrant(a, wp)
+ cb, sb, nb = cos_sin_quadrant(b, wp)
+ ca, cb = mpf_min_max([ca, cb])
+ sa, sb = mpf_min_max([sa, sb])
+ # Both functions are monotonic within one quadrant
+ if na == nb:
+ pass
+ # Guaranteed to contain both -1 and 1
+ elif nb - na >= 4:
+ return (fnone, fone), (fnone, fone)
+ else:
+ # cos has maximum between a and b
+ if na//4 != nb//4:
+ cb = fone
+ # cos has minimum
+ if (na-2)//4 != (nb-2)//4:
+ ca = fnone
+ # sin has maximum
+ if (na-1)//4 != (nb-1)//4:
+ sb = fone
+ # sin has minimum
+ if (na-3)//4 != (nb-3)//4:
+ sa = fnone
+ # Perturb to force interval rounding
+ more = from_man_exp((MPZ_ONE<= 1:
+ if sign:
+ return fnone
+ return fone
+ return v
+ ca = finalize(ca, round_floor)
+ cb = finalize(cb, round_ceiling)
+ sa = finalize(sa, round_floor)
+ sb = finalize(sb, round_ceiling)
+ return (ca,cb), (sa,sb)
+
+def mpi_cos(x, prec):
+ return mpi_cos_sin(x, prec)[0]
+
+def mpi_sin(x, prec):
+ return mpi_cos_sin(x, prec)[1]
+
+def mpi_tan(x, prec):
+ cos, sin = mpi_cos_sin(x, prec+20)
+ return mpi_div(sin, cos, prec)
+
+def mpi_cot(x, prec):
+ cos, sin = mpi_cos_sin(x, prec+20)
+ return mpi_div(cos, sin, prec)
+
+def mpi_from_str_a_b(x, y, percent, prec):
+ wp = prec + 20
+ xa = from_str(x, wp, round_floor)
+ xb = from_str(x, wp, round_ceiling)
+ #ya = from_str(y, wp, round_floor)
+ y = from_str(y, wp, round_ceiling)
+ assert mpf_ge(y, fzero)
+ if percent:
+ y = mpf_mul(MAX(mpf_abs(xa), mpf_abs(xb)), y, wp, round_ceiling)
+ y = mpf_div(y, from_int(100), wp, round_ceiling)
+ a = mpf_sub(xa, y, prec, round_floor)
+ b = mpf_add(xb, y, prec, round_ceiling)
+ return a, b
+
+def mpi_from_str(s, prec):
+ """
+ Parse an interval number given as a string.
+
+ Allowed forms are
+
+ "-1.23e-27"
+ Any single decimal floating-point literal.
+ "a +- b" or "a (b)"
+ a is the midpoint of the interval and b is the half-width
+ "a +- b%" or "a (b%)"
+ a is the midpoint of the interval and the half-width
+ is b percent of a (`a \times b / 100`).
+ "[a, b]"
+ The interval indicated directly.
+ "x[y,z]e"
+ x are shared digits, y and z are unequal digits, e is the exponent.
+
+ """
+ e = ValueError("Improperly formed interval number '%s'" % s)
+ s = s.replace(" ", "")
+ wp = prec + 20
+ if "+-" in s:
+ x, y = s.split("+-")
+ return mpi_from_str_a_b(x, y, False, prec)
+ # case 2
+ elif "(" in s:
+ # Don't confuse with a complex number (x,y)
+ if s[0] == "(" or ")" not in s:
+ raise e
+ s = s.replace(")", "")
+ percent = False
+ if "%" in s:
+ if s[-1] != "%":
+ raise e
+ percent = True
+ s = s.replace("%", "")
+ x, y = s.split("(")
+ return mpi_from_str_a_b(x, y, percent, prec)
+ elif "," in s:
+ if ('[' not in s) or (']' not in s):
+ raise e
+ if s[0] == '[':
+ # case 3
+ s = s.replace("[", "")
+ s = s.replace("]", "")
+ a, b = s.split(",")
+ a = from_str(a, prec, round_floor)
+ b = from_str(b, prec, round_ceiling)
+ return a, b
+ else:
+ # case 4
+ x, y = s.split('[')
+ y, z = y.split(',')
+ if 'e' in s:
+ z, e = z.split(']')
+ else:
+ z, e = z.rstrip(']'), ''
+ a = from_str(x+y+e, prec, round_floor)
+ b = from_str(x+z+e, prec, round_ceiling)
+ return a, b
+ else:
+ a = from_str(s, prec, round_floor)
+ b = from_str(s, prec, round_ceiling)
+ return a, b
+
+def mpi_to_str(x, dps, use_spaces=True, brackets='[]', mode='brackets', error_dps=4, **kwargs):
+ """
+ Convert a mpi interval to a string.
+
+ **Arguments**
+
+ *dps*
+ decimal places to use for printing
+ *use_spaces*
+ use spaces for more readable output, defaults to true
+ *brackets*
+ pair of strings (or two-character string) giving left and right brackets
+ *mode*
+ mode of display: 'plusminus', 'percent', 'brackets' (default) or 'diff'
+ *error_dps*
+ limit the error to *error_dps* digits (mode 'plusminus and 'percent')
+
+ Additional keyword arguments are forwarded to the mpf-to-string conversion
+ for the components of the output.
+
+ **Examples**
+
+ >>> from mpmath import mpi, mp
+ >>> mp.dps = 30
+ >>> x = mpi(1, 2)._mpi_
+ >>> mpi_to_str(x, 2, mode='plusminus')
+ '1.5 +- 0.5'
+ >>> mpi_to_str(x, 2, mode='percent')
+ '1.5 (33.33%)'
+ >>> mpi_to_str(x, 2, mode='brackets')
+ '[1.0, 2.0]'
+ >>> mpi_to_str(x, 2, mode='brackets' , brackets=('<', '>'))
+ '<1.0, 2.0>'
+ >>> x = mpi('5.2582327113062393041', '5.2582327113062749951')._mpi_
+ >>> mpi_to_str(x, 15, mode='diff')
+ '5.2582327113062[4, 7]'
+ >>> mpi_to_str(mpi(0)._mpi_, 2, mode='percent')
+ '0.0 (0.0%)'
+
+ """
+ prec = dps_to_prec(dps)
+ wp = prec + 20
+ a, b = x
+ mid = mpi_mid(x, prec)
+ delta = mpi_delta(x, prec)
+ a_str = to_str(a, dps, **kwargs)
+ b_str = to_str(b, dps, **kwargs)
+ mid_str = to_str(mid, dps, **kwargs)
+ sp = ""
+ if use_spaces:
+ sp = " "
+ br1, br2 = brackets
+ if mode == 'plusminus':
+ delta_str = to_str(mpf_shift(delta,-1), dps, **kwargs)
+ s = mid_str + sp + "+-" + sp + delta_str
+ elif mode == 'percent':
+ if mid == fzero:
+ p = fzero
+ else:
+ # p = 100 * delta(x) / (2*mid(x))
+ p = mpf_mul(delta, from_int(100))
+ p = mpf_div(p, mpf_mul(mid, from_int(2)), wp)
+ s = mid_str + sp + "(" + to_str(p, error_dps) + "%)"
+ elif mode == 'brackets':
+ s = br1 + a_str + "," + sp + b_str + br2
+ elif mode == 'diff':
+ # use more digits if str(x.a) and str(x.b) are equal
+ if a_str == b_str:
+ a_str = to_str(a, dps+3, **kwargs)
+ b_str = to_str(b, dps+3, **kwargs)
+ # separate mantissa and exponent
+ a = a_str.split('e')
+ if len(a) == 1:
+ a.append('')
+ b = b_str.split('e')
+ if len(b) == 1:
+ b.append('')
+ if a[1] == b[1]:
+ if a[0] != b[0]:
+ for i in xrange(len(a[0]) + 1):
+ if a[0][i] != b[0][i]:
+ break
+ s = (a[0][:i] + br1 + a[0][i:] + ',' + sp + b[0][i:] + br2
+ + 'e'*min(len(a[1]), 1) + a[1])
+ else: # no difference
+ s = a[0] + br1 + br2 + 'e'*min(len(a[1]), 1) + a[1]
+ else:
+ s = br1 + 'e'.join(a) + ',' + sp + 'e'.join(b) + br2
+ else:
+ raise ValueError("'%s' is unknown mode for printing mpi" % mode)
+ return s
+
+def mpci_add(x, y, prec):
+ a, b = x
+ c, d = y
+ return mpi_add(a, c, prec), mpi_add(b, d, prec)
+
+def mpci_sub(x, y, prec):
+ a, b = x
+ c, d = y
+ return mpi_sub(a, c, prec), mpi_sub(b, d, prec)
+
+def mpci_neg(x, prec=0):
+ a, b = x
+ return mpi_neg(a, prec), mpi_neg(b, prec)
+
+def mpci_pos(x, prec):
+ a, b = x
+ return mpi_pos(a, prec), mpi_pos(b, prec)
+
+def mpci_mul(x, y, prec):
+ # TODO: optimize for real/imag cases
+ a, b = x
+ c, d = y
+ r1 = mpi_mul(a,c)
+ r2 = mpi_mul(b,d)
+ re = mpi_sub(r1,r2,prec)
+ i1 = mpi_mul(a,d)
+ i2 = mpi_mul(b,c)
+ im = mpi_add(i1,i2,prec)
+ return re, im
+
+def mpci_div(x, y, prec):
+ # TODO: optimize for real/imag cases
+ a, b = x
+ c, d = y
+ wp = prec+20
+ m1 = mpi_square(c)
+ m2 = mpi_square(d)
+ m = mpi_add(m1,m2,wp)
+ re = mpi_add(mpi_mul(a,c), mpi_mul(b,d), wp)
+ im = mpi_sub(mpi_mul(b,c), mpi_mul(a,d), wp)
+ re = mpi_div(re, m, prec)
+ im = mpi_div(im, m, prec)
+ return re, im
+
+def mpci_exp(x, prec):
+ a, b = x
+ wp = prec+20
+ r = mpi_exp(a, wp)
+ c, s = mpi_cos_sin(b, wp)
+ a = mpi_mul(r, c, prec)
+ b = mpi_mul(r, s, prec)
+ return a, b
+
+def mpi_shift(x, n):
+ a, b = x
+ return mpf_shift(a,n), mpf_shift(b,n)
+
+def mpi_cosh_sinh(x, prec):
+ # TODO: accuracy for small x
+ wp = prec+20
+ e1 = mpi_exp(x, wp)
+ e2 = mpi_div(mpi_one, e1, wp)
+ c = mpi_add(e1, e2, prec)
+ s = mpi_sub(e1, e2, prec)
+ c = mpi_shift(c, -1)
+ s = mpi_shift(s, -1)
+ return c, s
+
+def mpci_cos(x, prec):
+ a, b = x
+ wp = prec+10
+ c, s = mpi_cos_sin(a, wp)
+ ch, sh = mpi_cosh_sinh(b, wp)
+ re = mpi_mul(c, ch, prec)
+ im = mpi_mul(s, sh, prec)
+ return re, mpi_neg(im)
+
+def mpci_sin(x, prec):
+ a, b = x
+ wp = prec+10
+ c, s = mpi_cos_sin(a, wp)
+ ch, sh = mpi_cosh_sinh(b, wp)
+ re = mpi_mul(s, ch, prec)
+ im = mpi_mul(c, sh, prec)
+ return re, im
+
+def mpci_abs(x, prec):
+ a, b = x
+ if a == mpi_zero:
+ return mpi_abs(b)
+ if b == mpi_zero:
+ return mpi_abs(a)
+ # Important: nonnegative
+ a = mpi_square(a)
+ b = mpi_square(b)
+ t = mpi_add(a, b, prec+20)
+ return mpi_sqrt(t, prec)
+
+def mpi_atan2(y, x, prec):
+ ya, yb = y
+ xa, xb = x
+ # Constrained to the real line
+ if ya == yb == fzero:
+ if mpf_ge(xa, fzero):
+ return mpi_zero
+ return mpi_pi(prec)
+ # Right half-plane
+ if mpf_ge(xa, fzero):
+ if mpf_ge(ya, fzero):
+ a = mpf_atan2(ya, xb, prec, round_floor)
+ else:
+ a = mpf_atan2(ya, xa, prec, round_floor)
+ if mpf_ge(yb, fzero):
+ b = mpf_atan2(yb, xa, prec, round_ceiling)
+ else:
+ b = mpf_atan2(yb, xb, prec, round_ceiling)
+ # Upper half-plane
+ elif mpf_ge(ya, fzero):
+ b = mpf_atan2(ya, xa, prec, round_ceiling)
+ if mpf_le(xb, fzero):
+ a = mpf_atan2(yb, xb, prec, round_floor)
+ else:
+ a = mpf_atan2(ya, xb, prec, round_floor)
+ # Lower half-plane
+ elif mpf_le(yb, fzero):
+ a = mpf_atan2(yb, xa, prec, round_floor)
+ if mpf_le(xb, fzero):
+ b = mpf_atan2(ya, xb, prec, round_ceiling)
+ else:
+ b = mpf_atan2(yb, xb, prec, round_ceiling)
+ # Covering the origin
+ else:
+ b = mpf_pi(prec, round_ceiling)
+ a = mpf_neg(b)
+ return a, b
+
+def mpci_arg(z, prec):
+ x, y = z
+ return mpi_atan2(y, x, prec)
+
+def mpci_log(z, prec):
+ x, y = z
+ re = mpi_log(mpci_abs(z, prec+20), prec)
+ im = mpci_arg(z, prec)
+ return re, im
+
+def mpci_pow(x, y, prec):
+ # TODO: recognize/speed up real cases, integer y
+ yre, yim = y
+ if yim == mpi_zero:
+ ya, yb = yre
+ if ya == yb:
+ sign, man, exp, bc = yb
+ if man and exp >= 0:
+ return mpci_pow_int(x, (-1)**sign * int(man<>= 1
+ return mpci_pos(result, prec)
+
+gamma_min_a = from_float(1.46163214496)
+gamma_min_b = from_float(1.46163214497)
+gamma_min = (gamma_min_a, gamma_min_b)
+gamma_mono_imag_a = from_float(-1.1)
+gamma_mono_imag_b = from_float(1.1)
+
+def mpi_overlap(x, y):
+ a, b = x
+ c, d = y
+ if mpf_lt(d, a): return False
+ if mpf_gt(c, b): return False
+ return True
+
+# type = 0 -- gamma
+# type = 1 -- factorial
+# type = 2 -- 1/gamma
+# type = 3 -- log-gamma
+
+def mpi_gamma(z, prec, type=0):
+ a, b = z
+ wp = prec+20
+
+ if type == 1:
+ return mpi_gamma(mpi_add(z, mpi_one, wp), prec, 0)
+
+ # increasing
+ if mpf_gt(a, gamma_min_b):
+ if type == 0:
+ c = mpf_gamma(a, prec, round_floor)
+ d = mpf_gamma(b, prec, round_ceiling)
+ elif type == 2:
+ c = mpf_rgamma(b, prec, round_floor)
+ d = mpf_rgamma(a, prec, round_ceiling)
+ elif type == 3:
+ c = mpf_loggamma(a, prec, round_floor)
+ d = mpf_loggamma(b, prec, round_ceiling)
+ # decreasing
+ elif mpf_gt(a, fzero) and mpf_lt(b, gamma_min_a):
+ if type == 0:
+ c = mpf_gamma(b, prec, round_floor)
+ d = mpf_gamma(a, prec, round_ceiling)
+ elif type == 2:
+ c = mpf_rgamma(a, prec, round_floor)
+ d = mpf_rgamma(b, prec, round_ceiling)
+ elif type == 3:
+ c = mpf_loggamma(b, prec, round_floor)
+ d = mpf_loggamma(a, prec, round_ceiling)
+ else:
+ # TODO: reflection formula
+ znew = mpi_add(z, mpi_one, wp)
+ if type == 0: return mpi_div(mpi_gamma(znew, prec+2, 0), z, prec)
+ if type == 2: return mpi_mul(mpi_gamma(znew, prec+2, 2), z, prec)
+ if type == 3: return mpi_sub(mpi_gamma(znew, prec+2, 3), mpi_log(z, prec+2), prec)
+ return c, d
+
+def mpci_gamma(z, prec, type=0):
+ (a1,a2), (b1,b2) = z
+
+ # Real case
+ if b1 == b2 == fzero and (type != 3 or mpf_gt(a1,fzero)):
+ return mpi_gamma(z, prec, type), mpi_zero
+
+ # Estimate precision
+ wp = prec+20
+ if type != 3:
+ amag = a2[2]+a2[3]
+ bmag = b2[2]+b2[3]
+ if a2 != fzero:
+ mag = max(amag, bmag)
+ else:
+ mag = bmag
+ an = abs(to_int(a2))
+ bn = abs(to_int(b2))
+ absn = max(an, bn)
+ gamma_size = max(0,absn*mag)
+ wp += bitcount(gamma_size)
+
+ # Assume type != 1
+ if type == 1:
+ (a1,a2) = mpi_add((a1,a2), mpi_one, wp); z = (a1,a2), (b1,b2)
+ type = 0
+
+ # Avoid non-monotonic region near the negative real axis
+ if mpf_lt(a1, gamma_min_b):
+ if mpi_overlap((b1,b2), (gamma_mono_imag_a, gamma_mono_imag_b)):
+ # TODO: reflection formula
+ #if mpf_lt(a2, mpf_shift(fone,-1)):
+ # znew = mpci_sub((mpi_one,mpi_zero),z,wp)
+ # ...
+ # Recurrence:
+ # gamma(z) = gamma(z+1)/z
+ znew = mpi_add((a1,a2), mpi_one, wp), (b1,b2)
+ if type == 0: return mpci_div(mpci_gamma(znew, prec+2, 0), z, prec)
+ if type == 2: return mpci_mul(mpci_gamma(znew, prec+2, 2), z, prec)
+ if type == 3: return mpci_sub(mpci_gamma(znew, prec+2, 3), mpci_log(z,prec+2), prec)
+
+ # Use monotonicity (except for a small region close to the
+ # origin and near poles)
+ # upper half-plane
+ if mpf_ge(b1, fzero):
+ minre = mpc_loggamma((a1,b2), wp, round_floor)
+ maxre = mpc_loggamma((a2,b1), wp, round_ceiling)
+ minim = mpc_loggamma((a1,b1), wp, round_floor)
+ maxim = mpc_loggamma((a2,b2), wp, round_ceiling)
+ # lower half-plane
+ elif mpf_le(b2, fzero):
+ minre = mpc_loggamma((a1,b1), wp, round_floor)
+ maxre = mpc_loggamma((a2,b2), wp, round_ceiling)
+ minim = mpc_loggamma((a2,b1), wp, round_floor)
+ maxim = mpc_loggamma((a1,b2), wp, round_ceiling)
+ # crosses real axis
+ else:
+ maxre = mpc_loggamma((a2,fzero), wp, round_ceiling)
+ # stretches more into the lower half-plane
+ if mpf_gt(mpf_neg(b1), b2):
+ minre = mpc_loggamma((a1,b1), wp, round_ceiling)
+ else:
+ minre = mpc_loggamma((a1,b2), wp, round_ceiling)
+ minim = mpc_loggamma((a2,b1), wp, round_floor)
+ maxim = mpc_loggamma((a2,b2), wp, round_floor)
+
+ w = (minre[0], maxre[0]), (minim[1], maxim[1])
+ if type == 3:
+ return mpi_pos(w[0], prec), mpi_pos(w[1], prec)
+ if type == 2:
+ w = mpci_neg(w)
+ return mpci_exp(w, prec)
+
+def mpi_loggamma(z, prec): return mpi_gamma(z, prec, type=3)
+def mpci_loggamma(z, prec): return mpci_gamma(z, prec, type=3)
+
+def mpi_rgamma(z, prec): return mpi_gamma(z, prec, type=2)
+def mpci_rgamma(z, prec): return mpci_gamma(z, prec, type=2)
+
+def mpi_factorial(z, prec): return mpi_gamma(z, prec, type=1)
+def mpci_factorial(z, prec): return mpci_gamma(z, prec, type=1)
diff --git a/lib/python3.10/site-packages/mpmath/matrices/__init__.py b/lib/python3.10/site-packages/mpmath/matrices/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..293697b9fcf8bd82d58ac4ff45acd73fadac82f9
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/matrices/__init__.py
@@ -0,0 +1,2 @@
+from . import eigen # to set methods
+from . import eigen_symmetric # to set methods
diff --git a/lib/python3.10/site-packages/mpmath/matrices/__pycache__/calculus.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/matrices/__pycache__/calculus.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1522645dd3589806b77f7a7d67174af175b66c01
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/matrices/__pycache__/calculus.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/matrices/calculus.py b/lib/python3.10/site-packages/mpmath/matrices/calculus.py
new file mode 100644
index 0000000000000000000000000000000000000000..7fae2a7a9a29898241ed41810331b480ff70798f
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/matrices/calculus.py
@@ -0,0 +1,531 @@
+from ..libmp.backend import xrange
+
+# TODO: should use diagonalization-based algorithms
+
+class MatrixCalculusMethods(object):
+
+ def _exp_pade(ctx, a):
+ """
+ Exponential of a matrix using Pade approximants.
+
+ See G. H. Golub, C. F. van Loan 'Matrix Computations',
+ third Ed., page 572
+
+ TODO:
+ - find a good estimate for q
+ - reduce the number of matrix multiplications to improve
+ performance
+ """
+ def eps_pade(p):
+ return ctx.mpf(2)**(3-2*p) * \
+ ctx.factorial(p)**2/(ctx.factorial(2*p)**2 * (2*p + 1))
+ q = 4
+ extraq = 8
+ while 1:
+ if eps_pade(q) < ctx.eps:
+ break
+ q += 1
+ q += extraq
+ j = int(max(1, ctx.mag(ctx.mnorm(a,'inf'))))
+ extra = q
+ prec = ctx.prec
+ ctx.dps += extra + 3
+ try:
+ a = a/2**j
+ na = a.rows
+ den = ctx.eye(na)
+ num = ctx.eye(na)
+ x = ctx.eye(na)
+ c = ctx.mpf(1)
+ for k in range(1, q+1):
+ c *= ctx.mpf(q - k + 1)/((2*q - k + 1) * k)
+ x = a*x
+ cx = c*x
+ num += cx
+ den += (-1)**k * cx
+ f = ctx.lu_solve_mat(den, num)
+ for k in range(j):
+ f = f*f
+ finally:
+ ctx.prec = prec
+ return f*1
+
+ def expm(ctx, A, method='taylor'):
+ r"""
+ Computes the matrix exponential of a square matrix `A`, which is defined
+ by the power series
+
+ .. math ::
+
+ \exp(A) = I + A + \frac{A^2}{2!} + \frac{A^3}{3!} + \ldots
+
+ With method='taylor', the matrix exponential is computed
+ using the Taylor series. With method='pade', Pade approximants
+ are used instead.
+
+ **Examples**
+
+ Basic examples::
+
+ >>> from mpmath import *
+ >>> mp.dps = 15; mp.pretty = True
+ >>> expm(zeros(3))
+ [1.0 0.0 0.0]
+ [0.0 1.0 0.0]
+ [0.0 0.0 1.0]
+ >>> expm(eye(3))
+ [2.71828182845905 0.0 0.0]
+ [ 0.0 2.71828182845905 0.0]
+ [ 0.0 0.0 2.71828182845905]
+ >>> expm([[1,1,0],[1,0,1],[0,1,0]])
+ [ 3.86814500615414 2.26812870852145 0.841130841230196]
+ [ 2.26812870852145 2.44114713886289 1.42699786729125]
+ [0.841130841230196 1.42699786729125 1.6000162976327]
+ >>> expm([[1,1,0],[1,0,1],[0,1,0]], method='pade')
+ [ 3.86814500615414 2.26812870852145 0.841130841230196]
+ [ 2.26812870852145 2.44114713886289 1.42699786729125]
+ [0.841130841230196 1.42699786729125 1.6000162976327]
+ >>> expm([[1+j, 0], [1+j,1]])
+ [(1.46869393991589 + 2.28735528717884j) 0.0]
+ [ (1.03776739863568 + 3.536943175722j) (2.71828182845905 + 0.0j)]
+
+ Matrices with large entries are allowed::
+
+ >>> expm(matrix([[1,2],[2,3]])**25)
+ [5.65024064048415e+2050488462815550 9.14228140091932e+2050488462815550]
+ [9.14228140091932e+2050488462815550 1.47925220414035e+2050488462815551]
+
+ The identity `\exp(A+B) = \exp(A) \exp(B)` does not hold for
+ noncommuting matrices::
+
+ >>> A = hilbert(3)
+ >>> B = A + eye(3)
+ >>> chop(mnorm(A*B - B*A))
+ 0.0
+ >>> chop(mnorm(expm(A+B) - expm(A)*expm(B)))
+ 0.0
+ >>> B = A + ones(3)
+ >>> mnorm(A*B - B*A)
+ 1.8
+ >>> mnorm(expm(A+B) - expm(A)*expm(B))
+ 42.0927851137247
+
+ """
+ if method == 'pade':
+ prec = ctx.prec
+ try:
+ A = ctx.matrix(A)
+ ctx.prec += 2*A.rows
+ res = ctx._exp_pade(A)
+ finally:
+ ctx.prec = prec
+ return res
+ A = ctx.matrix(A)
+ prec = ctx.prec
+ j = int(max(1, ctx.mag(ctx.mnorm(A,'inf'))))
+ j += int(0.5*prec**0.5)
+ try:
+ ctx.prec += 10 + 2*j
+ tol = +ctx.eps
+ A = A/2**j
+ T = A
+ Y = A**0 + A
+ k = 2
+ while 1:
+ T *= A * (1/ctx.mpf(k))
+ if ctx.mnorm(T, 'inf') < tol:
+ break
+ Y += T
+ k += 1
+ for k in xrange(j):
+ Y = Y*Y
+ finally:
+ ctx.prec = prec
+ Y *= 1
+ return Y
+
+ def cosm(ctx, A):
+ r"""
+ Gives the cosine of a square matrix `A`, defined in analogy
+ with the matrix exponential.
+
+ Examples::
+
+ >>> from mpmath import *
+ >>> mp.dps = 15; mp.pretty = True
+ >>> X = eye(3)
+ >>> cosm(X)
+ [0.54030230586814 0.0 0.0]
+ [ 0.0 0.54030230586814 0.0]
+ [ 0.0 0.0 0.54030230586814]
+ >>> X = hilbert(3)
+ >>> cosm(X)
+ [ 0.424403834569555 -0.316643413047167 -0.221474945949293]
+ [-0.316643413047167 0.820646708837824 -0.127183694770039]
+ [-0.221474945949293 -0.127183694770039 0.909236687217541]
+ >>> X = matrix([[1+j,-2],[0,-j]])
+ >>> cosm(X)
+ [(0.833730025131149 - 0.988897705762865j) (1.07485840848393 - 0.17192140544213j)]
+ [ 0.0 (1.54308063481524 + 0.0j)]
+ """
+ B = 0.5 * (ctx.expm(A*ctx.j) + ctx.expm(A*(-ctx.j)))
+ if not sum(A.apply(ctx.im).apply(abs)):
+ B = B.apply(ctx.re)
+ return B
+
+ def sinm(ctx, A):
+ r"""
+ Gives the sine of a square matrix `A`, defined in analogy
+ with the matrix exponential.
+
+ Examples::
+
+ >>> from mpmath import *
+ >>> mp.dps = 15; mp.pretty = True
+ >>> X = eye(3)
+ >>> sinm(X)
+ [0.841470984807897 0.0 0.0]
+ [ 0.0 0.841470984807897 0.0]
+ [ 0.0 0.0 0.841470984807897]
+ >>> X = hilbert(3)
+ >>> sinm(X)
+ [0.711608512150994 0.339783913247439 0.220742837314741]
+ [0.339783913247439 0.244113865695532 0.187231271174372]
+ [0.220742837314741 0.187231271174372 0.155816730769635]
+ >>> X = matrix([[1+j,-2],[0,-j]])
+ >>> sinm(X)
+ [(1.29845758141598 + 0.634963914784736j) (-1.96751511930922 + 0.314700021761367j)]
+ [ 0.0 (0.0 - 1.1752011936438j)]
+ """
+ B = (-0.5j) * (ctx.expm(A*ctx.j) - ctx.expm(A*(-ctx.j)))
+ if not sum(A.apply(ctx.im).apply(abs)):
+ B = B.apply(ctx.re)
+ return B
+
+ def _sqrtm_rot(ctx, A, _may_rotate):
+ # If the iteration fails to converge, cheat by performing
+ # a rotation by a complex number
+ u = ctx.j**0.3
+ return ctx.sqrtm(u*A, _may_rotate) / ctx.sqrt(u)
+
+ def sqrtm(ctx, A, _may_rotate=2):
+ r"""
+ Computes a square root of the square matrix `A`, i.e. returns
+ a matrix `B = A^{1/2}` such that `B^2 = A`. The square root
+ of a matrix, if it exists, is not unique.
+
+ **Examples**
+
+ Square roots of some simple matrices::
+
+ >>> from mpmath import *
+ >>> mp.dps = 15; mp.pretty = True
+ >>> sqrtm([[1,0], [0,1]])
+ [1.0 0.0]
+ [0.0 1.0]
+ >>> sqrtm([[0,0], [0,0]])
+ [0.0 0.0]
+ [0.0 0.0]
+ >>> sqrtm([[2,0],[0,1]])
+ [1.4142135623731 0.0]
+ [ 0.0 1.0]
+ >>> sqrtm([[1,1],[1,0]])
+ [ (0.920442065259926 - 0.21728689675164j) (0.568864481005783 + 0.351577584254143j)]
+ [(0.568864481005783 + 0.351577584254143j) (0.351577584254143 - 0.568864481005783j)]
+ >>> sqrtm([[1,0],[0,1]])
+ [1.0 0.0]
+ [0.0 1.0]
+ >>> sqrtm([[-1,0],[0,1]])
+ [(0.0 - 1.0j) 0.0]
+ [ 0.0 (1.0 + 0.0j)]
+ >>> sqrtm([[j,0],[0,j]])
+ [(0.707106781186547 + 0.707106781186547j) 0.0]
+ [ 0.0 (0.707106781186547 + 0.707106781186547j)]
+
+ A square root of a rotation matrix, giving the corresponding
+ half-angle rotation matrix::
+
+ >>> t1 = 0.75
+ >>> t2 = t1 * 0.5
+ >>> A1 = matrix([[cos(t1), -sin(t1)], [sin(t1), cos(t1)]])
+ >>> A2 = matrix([[cos(t2), -sin(t2)], [sin(t2), cos(t2)]])
+ >>> sqrtm(A1)
+ [0.930507621912314 -0.366272529086048]
+ [0.366272529086048 0.930507621912314]
+ >>> A2
+ [0.930507621912314 -0.366272529086048]
+ [0.366272529086048 0.930507621912314]
+
+ The identity `(A^2)^{1/2} = A` does not necessarily hold::
+
+ >>> A = matrix([[4,1,4],[7,8,9],[10,2,11]])
+ >>> sqrtm(A**2)
+ [ 4.0 1.0 4.0]
+ [ 7.0 8.0 9.0]
+ [10.0 2.0 11.0]
+ >>> sqrtm(A)**2
+ [ 4.0 1.0 4.0]
+ [ 7.0 8.0 9.0]
+ [10.0 2.0 11.0]
+ >>> A = matrix([[-4,1,4],[7,-8,9],[10,2,11]])
+ >>> sqrtm(A**2)
+ [ 7.43715112194995 -0.324127569985474 1.8481718827526]
+ [-0.251549715716942 9.32699765900402 2.48221180985147]
+ [ 4.11609388833616 0.775751877098258 13.017955697342]
+ >>> chop(sqrtm(A)**2)
+ [-4.0 1.0 4.0]
+ [ 7.0 -8.0 9.0]
+ [10.0 2.0 11.0]
+
+ For some matrices, a square root does not exist::
+
+ >>> sqrtm([[0,1], [0,0]])
+ Traceback (most recent call last):
+ ...
+ ZeroDivisionError: matrix is numerically singular
+
+ Two examples from the documentation for Matlab's ``sqrtm``::
+
+ >>> mp.dps = 15; mp.pretty = True
+ >>> sqrtm([[7,10],[15,22]])
+ [1.56669890360128 1.74077655955698]
+ [2.61116483933547 4.17786374293675]
+ >>>
+ >>> X = matrix(\
+ ... [[5,-4,1,0,0],
+ ... [-4,6,-4,1,0],
+ ... [1,-4,6,-4,1],
+ ... [0,1,-4,6,-4],
+ ... [0,0,1,-4,5]])
+ >>> Y = matrix(\
+ ... [[2,-1,-0,-0,-0],
+ ... [-1,2,-1,0,-0],
+ ... [0,-1,2,-1,0],
+ ... [-0,0,-1,2,-1],
+ ... [-0,-0,-0,-1,2]])
+ >>> mnorm(sqrtm(X) - Y)
+ 4.53155328326114e-19
+
+ """
+ A = ctx.matrix(A)
+ # Trivial
+ if A*0 == A:
+ return A
+ prec = ctx.prec
+ if _may_rotate:
+ d = ctx.det(A)
+ if abs(ctx.im(d)) < 16*ctx.eps and ctx.re(d) < 0:
+ return ctx._sqrtm_rot(A, _may_rotate-1)
+ try:
+ ctx.prec += 10
+ tol = ctx.eps * 128
+ Y = A
+ Z = I = A**0
+ k = 0
+ # Denman-Beavers iteration
+ while 1:
+ Yprev = Y
+ try:
+ Y, Z = 0.5*(Y+ctx.inverse(Z)), 0.5*(Z+ctx.inverse(Y))
+ except ZeroDivisionError:
+ if _may_rotate:
+ Y = ctx._sqrtm_rot(A, _may_rotate-1)
+ break
+ else:
+ raise
+ mag1 = ctx.mnorm(Y-Yprev, 'inf')
+ mag2 = ctx.mnorm(Y, 'inf')
+ if mag1 <= mag2*tol:
+ break
+ if _may_rotate and k > 6 and not mag1 < mag2 * 0.001:
+ return ctx._sqrtm_rot(A, _may_rotate-1)
+ k += 1
+ if k > ctx.prec:
+ raise ctx.NoConvergence
+ finally:
+ ctx.prec = prec
+ Y *= 1
+ return Y
+
+ def logm(ctx, A):
+ r"""
+ Computes a logarithm of the square matrix `A`, i.e. returns
+ a matrix `B = \log(A)` such that `\exp(B) = A`. The logarithm
+ of a matrix, if it exists, is not unique.
+
+ **Examples**
+
+ Logarithms of some simple matrices::
+
+ >>> from mpmath import *
+ >>> mp.dps = 15; mp.pretty = True
+ >>> X = eye(3)
+ >>> logm(X)
+ [0.0 0.0 0.0]
+ [0.0 0.0 0.0]
+ [0.0 0.0 0.0]
+ >>> logm(2*X)
+ [0.693147180559945 0.0 0.0]
+ [ 0.0 0.693147180559945 0.0]
+ [ 0.0 0.0 0.693147180559945]
+ >>> logm(expm(X))
+ [1.0 0.0 0.0]
+ [0.0 1.0 0.0]
+ [0.0 0.0 1.0]
+
+ A logarithm of a complex matrix::
+
+ >>> X = matrix([[2+j, 1, 3], [1-j, 1-2*j, 1], [-4, -5, j]])
+ >>> B = logm(X)
+ >>> nprint(B)
+ [ (0.808757 + 0.107759j) (2.20752 + 0.202762j) (1.07376 - 0.773874j)]
+ [ (0.905709 - 0.107795j) (0.0287395 - 0.824993j) (0.111619 + 0.514272j)]
+ [(-0.930151 + 0.399512j) (-2.06266 - 0.674397j) (0.791552 + 0.519839j)]
+ >>> chop(expm(B))
+ [(2.0 + 1.0j) 1.0 3.0]
+ [(1.0 - 1.0j) (1.0 - 2.0j) 1.0]
+ [ -4.0 -5.0 (0.0 + 1.0j)]
+
+ A matrix `X` close to the identity matrix, for which
+ `\log(\exp(X)) = \exp(\log(X)) = X` holds::
+
+ >>> X = eye(3) + hilbert(3)/4
+ >>> X
+ [ 1.25 0.125 0.0833333333333333]
+ [ 0.125 1.08333333333333 0.0625]
+ [0.0833333333333333 0.0625 1.05]
+ >>> logm(expm(X))
+ [ 1.25 0.125 0.0833333333333333]
+ [ 0.125 1.08333333333333 0.0625]
+ [0.0833333333333333 0.0625 1.05]
+ >>> expm(logm(X))
+ [ 1.25 0.125 0.0833333333333333]
+ [ 0.125 1.08333333333333 0.0625]
+ [0.0833333333333333 0.0625 1.05]
+
+ A logarithm of a rotation matrix, giving back the angle of
+ the rotation::
+
+ >>> t = 3.7
+ >>> A = matrix([[cos(t),sin(t)],[-sin(t),cos(t)]])
+ >>> chop(logm(A))
+ [ 0.0 -2.58318530717959]
+ [2.58318530717959 0.0]
+ >>> (2*pi-t)
+ 2.58318530717959
+
+ For some matrices, a logarithm does not exist::
+
+ >>> logm([[1,0], [0,0]])
+ Traceback (most recent call last):
+ ...
+ ZeroDivisionError: matrix is numerically singular
+
+ Logarithm of a matrix with large entries::
+
+ >>> logm(hilbert(3) * 10**20).apply(re)
+ [ 45.5597513593433 1.27721006042799 0.317662687717978]
+ [ 1.27721006042799 42.5222778973542 2.24003708791604]
+ [0.317662687717978 2.24003708791604 42.395212822267]
+
+ """
+ A = ctx.matrix(A)
+ prec = ctx.prec
+ try:
+ ctx.prec += 10
+ tol = ctx.eps * 128
+ I = A**0
+ B = A
+ n = 0
+ while 1:
+ B = ctx.sqrtm(B)
+ n += 1
+ if ctx.mnorm(B-I, 'inf') < 0.125:
+ break
+ T = X = B-I
+ L = X*0
+ k = 1
+ while 1:
+ if k & 1:
+ L += T / k
+ else:
+ L -= T / k
+ T *= X
+ if ctx.mnorm(T, 'inf') < tol:
+ break
+ k += 1
+ if k > ctx.prec:
+ raise ctx.NoConvergence
+ finally:
+ ctx.prec = prec
+ L *= 2**n
+ return L
+
+ def powm(ctx, A, r):
+ r"""
+ Computes `A^r = \exp(A \log r)` for a matrix `A` and complex
+ number `r`.
+
+ **Examples**
+
+ Powers and inverse powers of a matrix::
+
+ >>> from mpmath import *
+ >>> mp.dps = 15; mp.pretty = True
+ >>> A = matrix([[4,1,4],[7,8,9],[10,2,11]])
+ >>> powm(A, 2)
+ [ 63.0 20.0 69.0]
+ [174.0 89.0 199.0]
+ [164.0 48.0 179.0]
+ >>> chop(powm(powm(A, 4), 1/4.))
+ [ 4.0 1.0 4.0]
+ [ 7.0 8.0 9.0]
+ [10.0 2.0 11.0]
+ >>> powm(extraprec(20)(powm)(A, -4), -1/4.)
+ [ 4.0 1.0 4.0]
+ [ 7.0 8.0 9.0]
+ [10.0 2.0 11.0]
+ >>> chop(powm(powm(A, 1+0.5j), 1/(1+0.5j)))
+ [ 4.0 1.0 4.0]
+ [ 7.0 8.0 9.0]
+ [10.0 2.0 11.0]
+ >>> powm(extraprec(5)(powm)(A, -1.5), -1/(1.5))
+ [ 4.0 1.0 4.0]
+ [ 7.0 8.0 9.0]
+ [10.0 2.0 11.0]
+
+ A Fibonacci-generating matrix::
+
+ >>> powm([[1,1],[1,0]], 10)
+ [89.0 55.0]
+ [55.0 34.0]
+ >>> fib(10)
+ 55.0
+ >>> powm([[1,1],[1,0]], 6.5)
+ [(16.5166626964253 - 0.0121089837381789j) (10.2078589271083 + 0.0195927472575932j)]
+ [(10.2078589271083 + 0.0195927472575932j) (6.30880376931698 - 0.0317017309957721j)]
+ >>> (phi**6.5 - (1-phi)**6.5)/sqrt(5)
+ (10.2078589271083 - 0.0195927472575932j)
+ >>> powm([[1,1],[1,0]], 6.2)
+ [ (14.3076953002666 - 0.008222855781077j) (8.81733464837593 + 0.0133048601383712j)]
+ [(8.81733464837593 + 0.0133048601383712j) (5.49036065189071 - 0.0215277159194482j)]
+ >>> (phi**6.2 - (1-phi)**6.2)/sqrt(5)
+ (8.81733464837593 - 0.0133048601383712j)
+
+ """
+ A = ctx.matrix(A)
+ r = ctx.convert(r)
+ prec = ctx.prec
+ try:
+ ctx.prec += 10
+ if ctx.isint(r):
+ v = A ** int(r)
+ elif ctx.isint(r*2):
+ y = int(r*2)
+ v = ctx.sqrtm(A) ** y
+ else:
+ v = ctx.expm(r*ctx.logm(A))
+ finally:
+ ctx.prec = prec
+ v *= 1
+ return v
diff --git a/lib/python3.10/site-packages/mpmath/matrices/eigen.py b/lib/python3.10/site-packages/mpmath/matrices/eigen.py
new file mode 100644
index 0000000000000000000000000000000000000000..885d604203195b695183329acc637de91aeaf5ea
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/matrices/eigen.py
@@ -0,0 +1,877 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+##################################################################################################
+# module for the eigenvalue problem
+# Copyright 2013 Timo Hartmann (thartmann15 at gmail.com)
+#
+# todo:
+# - implement balancing
+# - agressive early deflation
+#
+##################################################################################################
+
+"""
+The eigenvalue problem
+----------------------
+
+This file contains routines for the eigenvalue problem.
+
+high level routines:
+
+ hessenberg : reduction of a real or complex square matrix to upper Hessenberg form
+ schur : reduction of a real or complex square matrix to upper Schur form
+ eig : eigenvalues and eigenvectors of a real or complex square matrix
+
+low level routines:
+
+ hessenberg_reduce_0 : reduction of a real or complex square matrix to upper Hessenberg form
+ hessenberg_reduce_1 : auxiliary routine to hessenberg_reduce_0
+ qr_step : a single implicitly shifted QR step for an upper Hessenberg matrix
+ hessenberg_qr : Schur decomposition of an upper Hessenberg matrix
+ eig_tr_r : right eigenvectors of an upper triangular matrix
+ eig_tr_l : left eigenvectors of an upper triangular matrix
+"""
+
+from ..libmp.backend import xrange
+
+class Eigen(object):
+ pass
+
+def defun(f):
+ setattr(Eigen, f.__name__, f)
+ return f
+
+def hessenberg_reduce_0(ctx, A, T):
+ """
+ This routine computes the (upper) Hessenberg decomposition of a square matrix A.
+ Given A, an unitary matrix Q is calculated such that
+
+ Q' A Q = H and Q' Q = Q Q' = 1
+
+ where H is an upper Hessenberg matrix, meaning that it only contains zeros
+ below the first subdiagonal. Here ' denotes the hermitian transpose (i.e.
+ transposition and conjugation).
+
+ parameters:
+ A (input/output) On input, A contains the square matrix A of
+ dimension (n,n). On output, A contains a compressed representation
+ of Q and H.
+ T (output) An array of length n containing the first elements of
+ the Householder reflectors.
+ """
+
+ # internally we work with householder reflections from the right.
+ # let u be a row vector (i.e. u[i]=A[i,:i]). then
+ # Q is build up by reflectors of the type (1-v'v) where v is a suitable
+ # modification of u. these reflectors are applyed to A from the right.
+ # because we work with reflectors from the right we have to start with
+ # the bottom row of A and work then upwards (this corresponds to
+ # some kind of RQ decomposition).
+ # the first part of the vectors v (i.e. A[i,:(i-1)]) are stored as row vectors
+ # in the lower left part of A (excluding the diagonal and subdiagonal).
+ # the last entry of v is stored in T.
+ # the upper right part of A (including diagonal and subdiagonal) becomes H.
+
+
+ n = A.rows
+ if n <= 2: return
+
+ for i in xrange(n-1, 1, -1):
+
+ # scale the vector
+
+ scale = 0
+ for k in xrange(0, i):
+ scale += abs(ctx.re(A[i,k])) + abs(ctx.im(A[i,k]))
+
+ scale_inv = 0
+ if scale != 0:
+ scale_inv = 1 / scale
+
+ if scale == 0 or ctx.isinf(scale_inv):
+ # sadly there are floating point numbers not equal to zero whose reciprocal is infinity
+ T[i] = 0
+ A[i,i-1] = 0
+ continue
+
+ # calculate parameters for housholder transformation
+
+ H = 0
+ for k in xrange(0, i):
+ A[i,k] *= scale_inv
+ rr = ctx.re(A[i,k])
+ ii = ctx.im(A[i,k])
+ H += rr * rr + ii * ii
+
+ F = A[i,i-1]
+ f = abs(F)
+ G = ctx.sqrt(H)
+ A[i,i-1] = - G * scale
+
+ if f == 0:
+ T[i] = G
+ else:
+ ff = F / f
+ T[i] = F + G * ff
+ A[i,i-1] *= ff
+
+ H += G * f
+ H = 1 / ctx.sqrt(H)
+
+ T[i] *= H
+ for k in xrange(0, i - 1):
+ A[i,k] *= H
+
+ for j in xrange(0, i):
+ # apply housholder transformation (from right)
+
+ G = ctx.conj(T[i]) * A[j,i-1]
+ for k in xrange(0, i-1):
+ G += ctx.conj(A[i,k]) * A[j,k]
+
+ A[j,i-1] -= G * T[i]
+ for k in xrange(0, i-1):
+ A[j,k] -= G * A[i,k]
+
+ for j in xrange(0, n):
+ # apply housholder transformation (from left)
+
+ G = T[i] * A[i-1,j]
+ for k in xrange(0, i-1):
+ G += A[i,k] * A[k,j]
+
+ A[i-1,j] -= G * ctx.conj(T[i])
+ for k in xrange(0, i-1):
+ A[k,j] -= G * ctx.conj(A[i,k])
+
+
+
+def hessenberg_reduce_1(ctx, A, T):
+ """
+ This routine forms the unitary matrix Q described in hessenberg_reduce_0.
+
+ parameters:
+ A (input/output) On input, A is the same matrix as delivered by
+ hessenberg_reduce_0. On output, A is set to Q.
+
+ T (input) On input, T is the same array as delivered by hessenberg_reduce_0.
+ """
+
+ n = A.rows
+
+ if n == 1:
+ A[0,0] = 1
+ return
+
+ A[0,0] = A[1,1] = 1
+ A[0,1] = A[1,0] = 0
+
+ for i in xrange(2, n):
+ if T[i] != 0:
+
+ for j in xrange(0, i):
+ G = T[i] * A[i-1,j]
+ for k in xrange(0, i-1):
+ G += A[i,k] * A[k,j]
+
+ A[i-1,j] -= G * ctx.conj(T[i])
+ for k in xrange(0, i-1):
+ A[k,j] -= G * ctx.conj(A[i,k])
+
+ A[i,i] = 1
+ for j in xrange(0, i):
+ A[j,i] = A[i,j] = 0
+
+
+
+@defun
+def hessenberg(ctx, A, overwrite_a = False):
+ """
+ This routine computes the Hessenberg decomposition of a square matrix A.
+ Given A, an unitary matrix Q is determined such that
+
+ Q' A Q = H and Q' Q = Q Q' = 1
+
+ where H is an upper right Hessenberg matrix. Here ' denotes the hermitian
+ transpose (i.e. transposition and conjugation).
+
+ input:
+ A : a real or complex square matrix
+ overwrite_a : if true, allows modification of A which may improve
+ performance. if false, A is not modified.
+
+ output:
+ Q : an unitary matrix
+ H : an upper right Hessenberg matrix
+
+ example:
+ >>> from mpmath import mp
+ >>> A = mp.matrix([[3, -1, 2], [2, 5, -5], [-2, -3, 7]])
+ >>> Q, H = mp.hessenberg(A)
+ >>> mp.nprint(H, 3) # doctest:+SKIP
+ [ 3.15 2.23 4.44]
+ [-0.769 4.85 3.05]
+ [ 0.0 3.61 7.0]
+ >>> print(mp.chop(A - Q * H * Q.transpose_conj()))
+ [0.0 0.0 0.0]
+ [0.0 0.0 0.0]
+ [0.0 0.0 0.0]
+
+ return value: (Q, H)
+ """
+
+ n = A.rows
+
+ if n == 1:
+ return (ctx.matrix([[1]]), A)
+
+ if not overwrite_a:
+ A = A.copy()
+
+ T = ctx.matrix(n, 1)
+
+ hessenberg_reduce_0(ctx, A, T)
+ Q = A.copy()
+ hessenberg_reduce_1(ctx, Q, T)
+
+ for x in xrange(n):
+ for y in xrange(x+2, n):
+ A[y,x] = 0
+
+ return Q, A
+
+
+###########################################################################
+
+
+def qr_step(ctx, n0, n1, A, Q, shift):
+ """
+ This subroutine executes a single implicitly shifted QR step applied to an
+ upper Hessenberg matrix A. Given A and shift as input, first an QR
+ decomposition is calculated:
+
+ Q R = A - shift * 1 .
+
+ The output is then following matrix:
+
+ R Q + shift * 1
+
+ parameters:
+ n0, n1 (input) Two integers which specify the submatrix A[n0:n1,n0:n1]
+ on which this subroutine operators. The subdiagonal elements
+ to the left and below this submatrix must be deflated (i.e. zero).
+ following restriction is imposed: n1>=n0+2
+ A (input/output) On input, A is an upper Hessenberg matrix.
+ On output, A is replaced by "R Q + shift * 1"
+ Q (input/output) The parameter Q is multiplied by the unitary matrix
+ Q arising from the QR decomposition. Q can also be false, in which
+ case the unitary matrix Q is not computated.
+ shift (input) a complex number specifying the shift. idealy close to an
+ eigenvalue of the bottemmost part of the submatrix A[n0:n1,n0:n1].
+
+ references:
+ Stoer, Bulirsch - Introduction to Numerical Analysis.
+ Kresser : Numerical Methods for General and Structured Eigenvalue Problems
+ """
+
+ # implicitly shifted and bulge chasing is explained at p.398/399 in "Stoer, Bulirsch - Introduction to Numerical Analysis"
+ # for bulge chasing see also "Watkins - The Matrix Eigenvalue Problem" sec.4.5,p.173
+
+ # the Givens rotation we used is determined as follows: let c,s be two complex
+ # numbers. then we have following relation:
+ #
+ # v = sqrt(|c|^2 + |s|^2)
+ #
+ # 1/v [ c~ s~] [c] = [v]
+ # [-s c ] [s] [0]
+ #
+ # the matrix on the left is our Givens rotation.
+
+ n = A.rows
+
+ # first step
+
+ # calculate givens rotation
+ c = A[n0 ,n0] - shift
+ s = A[n0+1,n0]
+
+ v = ctx.hypot(ctx.hypot(ctx.re(c), ctx.im(c)), ctx.hypot(ctx.re(s), ctx.im(s)))
+
+ if v == 0:
+ v = 1
+ c = 1
+ s = 0
+ else:
+ c /= v
+ s /= v
+
+ cc = ctx.conj(c)
+ cs = ctx.conj(s)
+
+ for k in xrange(n0, n):
+ # apply givens rotation from the left
+ x = A[n0 ,k]
+ y = A[n0+1,k]
+ A[n0 ,k] = cc * x + cs * y
+ A[n0+1,k] = c * y - s * x
+
+ for k in xrange(min(n1, n0+3)):
+ # apply givens rotation from the right
+ x = A[k,n0 ]
+ y = A[k,n0+1]
+ A[k,n0 ] = c * x + s * y
+ A[k,n0+1] = cc * y - cs * x
+
+ if not isinstance(Q, bool):
+ for k in xrange(n):
+ # eigenvectors
+ x = Q[k,n0 ]
+ y = Q[k,n0+1]
+ Q[k,n0 ] = c * x + s * y
+ Q[k,n0+1] = cc * y - cs * x
+
+ # chase the bulge
+
+ for j in xrange(n0, n1 - 2):
+ # calculate givens rotation
+
+ c = A[j+1,j]
+ s = A[j+2,j]
+
+ v = ctx.hypot(ctx.hypot(ctx.re(c), ctx.im(c)), ctx.hypot(ctx.re(s), ctx.im(s)))
+
+ if v == 0:
+ A[j+1,j] = 0
+ v = 1
+ c = 1
+ s = 0
+ else:
+ A[j+1,j] = v
+ c /= v
+ s /= v
+
+ A[j+2,j] = 0
+
+ cc = ctx.conj(c)
+ cs = ctx.conj(s)
+
+ for k in xrange(j+1, n):
+ # apply givens rotation from the left
+ x = A[j+1,k]
+ y = A[j+2,k]
+ A[j+1,k] = cc * x + cs * y
+ A[j+2,k] = c * y - s * x
+
+ for k in xrange(0, min(n1, j+4)):
+ # apply givens rotation from the right
+ x = A[k,j+1]
+ y = A[k,j+2]
+ A[k,j+1] = c * x + s * y
+ A[k,j+2] = cc * y - cs * x
+
+ if not isinstance(Q, bool):
+ for k in xrange(0, n):
+ # eigenvectors
+ x = Q[k,j+1]
+ y = Q[k,j+2]
+ Q[k,j+1] = c * x + s * y
+ Q[k,j+2] = cc * y - cs * x
+
+
+
+def hessenberg_qr(ctx, A, Q):
+ """
+ This routine computes the Schur decomposition of an upper Hessenberg matrix A.
+ Given A, an unitary matrix Q is determined such that
+
+ Q' A Q = R and Q' Q = Q Q' = 1
+
+ where R is an upper right triangular matrix. Here ' denotes the hermitian
+ transpose (i.e. transposition and conjugation).
+
+ parameters:
+ A (input/output) On input, A contains an upper Hessenberg matrix.
+ On output, A is replace by the upper right triangluar matrix R.
+
+ Q (input/output) The parameter Q is multiplied by the unitary
+ matrix Q arising from the Schur decomposition. Q can also be
+ false, in which case the unitary matrix Q is not computated.
+ """
+
+ n = A.rows
+
+ norm = 0
+ for x in xrange(n):
+ for y in xrange(min(x+2, n)):
+ norm += ctx.re(A[y,x]) ** 2 + ctx.im(A[y,x]) ** 2
+ norm = ctx.sqrt(norm) / n
+
+ if norm == 0:
+ return
+
+ n0 = 0
+ n1 = n
+
+ eps = ctx.eps / (100 * n)
+ maxits = ctx.dps * 4
+
+ its = totalits = 0
+
+ while 1:
+ # kressner p.32 algo 3
+ # the active submatrix is A[n0:n1,n0:n1]
+
+ k = n0
+
+ while k + 1 < n1:
+ s = abs(ctx.re(A[k,k])) + abs(ctx.im(A[k,k])) + abs(ctx.re(A[k+1,k+1])) + abs(ctx.im(A[k+1,k+1]))
+ if s < eps * norm:
+ s = norm
+ if abs(A[k+1,k]) < eps * s:
+ break
+ k += 1
+
+ if k + 1 < n1:
+ # deflation found at position (k+1, k)
+
+ A[k+1,k] = 0
+ n0 = k + 1
+
+ its = 0
+
+ if n0 + 1 >= n1:
+ # block of size at most two has converged
+ n0 = 0
+ n1 = k + 1
+ if n1 < 2:
+ # QR algorithm has converged
+ return
+ else:
+ if (its % 30) == 10:
+ # exceptional shift
+ shift = A[n1-1,n1-2]
+ elif (its % 30) == 20:
+ # exceptional shift
+ shift = abs(A[n1-1,n1-2])
+ elif (its % 30) == 29:
+ # exceptional shift
+ shift = norm
+ else:
+ # A = [ a b ] det(x-A)=x*x-x*tr(A)+det(A)
+ # [ c d ]
+ #
+ # eigenvalues bad: (tr(A)+sqrt((tr(A))**2-4*det(A)))/2
+ # bad because of cancellation if |c| is small and |a-d| is small, too.
+ #
+ # eigenvalues good: (a+d+sqrt((a-d)**2+4*b*c))/2
+
+ t = A[n1-2,n1-2] + A[n1-1,n1-1]
+ s = (A[n1-1,n1-1] - A[n1-2,n1-2]) ** 2 + 4 * A[n1-1,n1-2] * A[n1-2,n1-1]
+ if ctx.re(s) > 0:
+ s = ctx.sqrt(s)
+ else:
+ s = ctx.sqrt(-s) * 1j
+ a = (t + s) / 2
+ b = (t - s) / 2
+ if abs(A[n1-1,n1-1] - a) > abs(A[n1-1,n1-1] - b):
+ shift = b
+ else:
+ shift = a
+
+ its += 1
+ totalits += 1
+
+ qr_step(ctx, n0, n1, A, Q, shift)
+
+ if its > maxits:
+ raise RuntimeError("qr: failed to converge after %d steps" % its)
+
+
+@defun
+def schur(ctx, A, overwrite_a = False):
+ """
+ This routine computes the Schur decomposition of a square matrix A.
+ Given A, an unitary matrix Q is determined such that
+
+ Q' A Q = R and Q' Q = Q Q' = 1
+
+ where R is an upper right triangular matrix. Here ' denotes the
+ hermitian transpose (i.e. transposition and conjugation).
+
+ input:
+ A : a real or complex square matrix
+ overwrite_a : if true, allows modification of A which may improve
+ performance. if false, A is not modified.
+
+ output:
+ Q : an unitary matrix
+ R : an upper right triangular matrix
+
+ return value: (Q, R)
+
+ example:
+ >>> from mpmath import mp
+ >>> A = mp.matrix([[3, -1, 2], [2, 5, -5], [-2, -3, 7]])
+ >>> Q, R = mp.schur(A)
+ >>> mp.nprint(R, 3) # doctest:+SKIP
+ [2.0 0.417 -2.53]
+ [0.0 4.0 -4.74]
+ [0.0 0.0 9.0]
+ >>> print(mp.chop(A - Q * R * Q.transpose_conj()))
+ [0.0 0.0 0.0]
+ [0.0 0.0 0.0]
+ [0.0 0.0 0.0]
+
+ warning: The Schur decomposition is not unique.
+ """
+
+ n = A.rows
+
+ if n == 1:
+ return (ctx.matrix([[1]]), A)
+
+ if not overwrite_a:
+ A = A.copy()
+
+ T = ctx.matrix(n, 1)
+
+ hessenberg_reduce_0(ctx, A, T)
+ Q = A.copy()
+ hessenberg_reduce_1(ctx, Q, T)
+
+ for x in xrange(n):
+ for y in xrange(x + 2, n):
+ A[y,x] = 0
+
+ hessenberg_qr(ctx, A, Q)
+
+ return Q, A
+
+
+def eig_tr_r(ctx, A):
+ """
+ This routine calculates the right eigenvectors of an upper right triangular matrix.
+
+ input:
+ A an upper right triangular matrix
+
+ output:
+ ER a matrix whose columns form the right eigenvectors of A
+
+ return value: ER
+ """
+
+ # this subroutine is inspired by the lapack routines ctrevc.f,clatrs.f
+
+ n = A.rows
+
+ ER = ctx.eye(n)
+
+ eps = ctx.eps
+
+ unfl = ctx.ldexp(ctx.one, -ctx.prec * 30)
+ # since mpmath effectively has no limits on the exponent, we simply scale doubles up
+ # original double has prec*20
+
+ smlnum = unfl * (n / eps)
+ simin = 1 / ctx.sqrt(eps)
+
+ rmax = 1
+
+ for i in xrange(1, n):
+ s = A[i,i]
+
+ smin = max(eps * abs(s), smlnum)
+
+ for j in xrange(i - 1, -1, -1):
+
+ r = 0
+ for k in xrange(j + 1, i + 1):
+ r += A[j,k] * ER[k,i]
+
+ t = A[j,j] - s
+ if abs(t) < smin:
+ t = smin
+
+ r = -r / t
+ ER[j,i] = r
+
+ rmax = max(rmax, abs(r))
+ if rmax > simin:
+ for k in xrange(j, i+1):
+ ER[k,i] /= rmax
+ rmax = 1
+
+ if rmax != 1:
+ for k in xrange(0, i + 1):
+ ER[k,i] /= rmax
+
+ return ER
+
+def eig_tr_l(ctx, A):
+ """
+ This routine calculates the left eigenvectors of an upper right triangular matrix.
+
+ input:
+ A an upper right triangular matrix
+
+ output:
+ EL a matrix whose rows form the left eigenvectors of A
+
+ return value: EL
+ """
+
+ n = A.rows
+
+ EL = ctx.eye(n)
+
+ eps = ctx.eps
+
+ unfl = ctx.ldexp(ctx.one, -ctx.prec * 30)
+ # since mpmath effectively has no limits on the exponent, we simply scale doubles up
+ # original double has prec*20
+
+ smlnum = unfl * (n / eps)
+ simin = 1 / ctx.sqrt(eps)
+
+ rmax = 1
+
+ for i in xrange(0, n - 1):
+ s = A[i,i]
+
+ smin = max(eps * abs(s), smlnum)
+
+ for j in xrange(i + 1, n):
+
+ r = 0
+ for k in xrange(i, j):
+ r += EL[i,k] * A[k,j]
+
+ t = A[j,j] - s
+ if abs(t) < smin:
+ t = smin
+
+ r = -r / t
+ EL[i,j] = r
+
+ rmax = max(rmax, abs(r))
+ if rmax > simin:
+ for k in xrange(i, j + 1):
+ EL[i,k] /= rmax
+ rmax = 1
+
+ if rmax != 1:
+ for k in xrange(i, n):
+ EL[i,k] /= rmax
+
+ return EL
+
+@defun
+def eig(ctx, A, left = False, right = True, overwrite_a = False):
+ """
+ This routine computes the eigenvalues and optionally the left and right
+ eigenvectors of a square matrix A. Given A, a vector E and matrices ER
+ and EL are calculated such that
+
+ A ER[:,i] = E[i] ER[:,i]
+ EL[i,:] A = EL[i,:] E[i]
+
+ E contains the eigenvalues of A. The columns of ER contain the right eigenvectors
+ of A whereas the rows of EL contain the left eigenvectors.
+
+
+ input:
+ A : a real or complex square matrix of shape (n, n)
+ left : if true, the left eigenvectors are calculated.
+ right : if true, the right eigenvectors are calculated.
+ overwrite_a : if true, allows modification of A which may improve
+ performance. if false, A is not modified.
+
+ output:
+ E : a list of length n containing the eigenvalues of A.
+ ER : a matrix whose columns contain the right eigenvectors of A.
+ EL : a matrix whose rows contain the left eigenvectors of A.
+
+ return values:
+ E if left and right are both false.
+ (E, ER) if right is true and left is false.
+ (E, EL) if left is true and right is false.
+ (E, EL, ER) if left and right are true.
+
+
+ examples:
+ >>> from mpmath import mp
+ >>> A = mp.matrix([[3, -1, 2], [2, 5, -5], [-2, -3, 7]])
+ >>> E, ER = mp.eig(A)
+ >>> print(mp.chop(A * ER[:,0] - E[0] * ER[:,0]))
+ [0.0]
+ [0.0]
+ [0.0]
+
+ >>> E, EL, ER = mp.eig(A,left = True, right = True)
+ >>> E, EL, ER = mp.eig_sort(E, EL, ER)
+ >>> mp.nprint(E)
+ [2.0, 4.0, 9.0]
+ >>> print(mp.chop(A * ER[:,0] - E[0] * ER[:,0]))
+ [0.0]
+ [0.0]
+ [0.0]
+ >>> print(mp.chop( EL[0,:] * A - EL[0,:] * E[0]))
+ [0.0 0.0 0.0]
+
+ warning:
+ - If there are multiple eigenvalues, the eigenvectors do not necessarily
+ span the whole vectorspace, i.e. ER and EL may have not full rank.
+ Furthermore in that case the eigenvectors are numerical ill-conditioned.
+ - In the general case the eigenvalues have no natural order.
+
+ see also:
+ - eigh (or eigsy, eighe) for the symmetric eigenvalue problem.
+ - eig_sort for sorting of eigenvalues and eigenvectors
+ """
+
+ n = A.rows
+
+ if n == 1:
+ if left and (not right):
+ return ([A[0]], ctx.matrix([[1]]))
+
+ if right and (not left):
+ return ([A[0]], ctx.matrix([[1]]))
+
+ return ([A[0]], ctx.matrix([[1]]), ctx.matrix([[1]]))
+
+ if not overwrite_a:
+ A = A.copy()
+
+ T = ctx.zeros(n, 1)
+
+ hessenberg_reduce_0(ctx, A, T)
+
+ if left or right:
+ Q = A.copy()
+ hessenberg_reduce_1(ctx, Q, T)
+ else:
+ Q = False
+
+ for x in xrange(n):
+ for y in xrange(x + 2, n):
+ A[y,x] = 0
+
+ hessenberg_qr(ctx, A, Q)
+
+ E = [0 for i in xrange(n)]
+ for i in xrange(n):
+ E[i] = A[i,i]
+
+ if not (left or right):
+ return E
+
+ if left:
+ EL = eig_tr_l(ctx, A)
+ EL = EL * Q.transpose_conj()
+
+ if right:
+ ER = eig_tr_r(ctx, A)
+ ER = Q * ER
+
+ if left and (not right):
+ return (E, EL)
+
+ if right and (not left):
+ return (E, ER)
+
+ return (E, EL, ER)
+
+@defun
+def eig_sort(ctx, E, EL = False, ER = False, f = "real"):
+ """
+ This routine sorts the eigenvalues and eigenvectors delivered by ``eig``.
+
+ parameters:
+ E : the eigenvalues as delivered by eig
+ EL : the left eigenvectors as delivered by eig, or false
+ ER : the right eigenvectors as delivered by eig, or false
+ f : either a string ("real" sort by increasing real part, "imag" sort by
+ increasing imag part, "abs" sort by absolute value) or a function
+ mapping complexs to the reals, i.e. ``f = lambda x: -mp.re(x) ``
+ would sort the eigenvalues by decreasing real part.
+
+ return values:
+ E if EL and ER are both false.
+ (E, ER) if ER is not false and left is false.
+ (E, EL) if EL is not false and right is false.
+ (E, EL, ER) if EL and ER are not false.
+
+ example:
+ >>> from mpmath import mp
+ >>> A = mp.matrix([[3, -1, 2], [2, 5, -5], [-2, -3, 7]])
+ >>> E, EL, ER = mp.eig(A,left = True, right = True)
+ >>> E, EL, ER = mp.eig_sort(E, EL, ER)
+ >>> mp.nprint(E)
+ [2.0, 4.0, 9.0]
+ >>> E, EL, ER = mp.eig_sort(E, EL, ER,f = lambda x: -mp.re(x))
+ >>> mp.nprint(E)
+ [9.0, 4.0, 2.0]
+ >>> print(mp.chop(A * ER[:,0] - E[0] * ER[:,0]))
+ [0.0]
+ [0.0]
+ [0.0]
+ >>> print(mp.chop( EL[0,:] * A - EL[0,:] * E[0]))
+ [0.0 0.0 0.0]
+ """
+
+ if isinstance(f, str):
+ if f == "real":
+ f = ctx.re
+ elif f == "imag":
+ f = ctx.im
+ elif f == "abs":
+ f = abs
+ else:
+ raise RuntimeError("unknown function %s" % f)
+
+ n = len(E)
+
+ # Sort eigenvalues (bubble-sort)
+
+ for i in xrange(n):
+ imax = i
+ s = f(E[i]) # s is the current maximal element
+
+ for j in xrange(i + 1, n):
+ c = f(E[j])
+ if c < s:
+ s = c
+ imax = j
+
+ if imax != i:
+ # swap eigenvalues
+
+ z = E[i]
+ E[i] = E[imax]
+ E[imax] = z
+
+ if not isinstance(EL, bool):
+ for j in xrange(n):
+ z = EL[i,j]
+ EL[i,j] = EL[imax,j]
+ EL[imax,j] = z
+
+ if not isinstance(ER, bool):
+ for j in xrange(n):
+ z = ER[j,i]
+ ER[j,i] = ER[j,imax]
+ ER[j,imax] = z
+
+ if isinstance(EL, bool) and isinstance(ER, bool):
+ return E
+
+ if isinstance(EL, bool) and not(isinstance(ER, bool)):
+ return (E, ER)
+
+ if isinstance(ER, bool) and not(isinstance(EL, bool)):
+ return (E, EL)
+
+ return (E, EL, ER)
diff --git a/lib/python3.10/site-packages/mpmath/matrices/eigen_symmetric.py b/lib/python3.10/site-packages/mpmath/matrices/eigen_symmetric.py
new file mode 100644
index 0000000000000000000000000000000000000000..c82c0bb061d22c37a89f82a0b9bdab3e9ba7ddde
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/matrices/eigen_symmetric.py
@@ -0,0 +1,1807 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+##################################################################################################
+# module for the symmetric eigenvalue problem
+# Copyright 2013 Timo Hartmann (thartmann15 at gmail.com)
+#
+# todo:
+# - implement balancing
+#
+##################################################################################################
+
+"""
+The symmetric eigenvalue problem.
+---------------------------------
+
+This file contains routines for the symmetric eigenvalue problem.
+
+high level routines:
+
+ eigsy : real symmetric (ordinary) eigenvalue problem
+ eighe : complex hermitian (ordinary) eigenvalue problem
+ eigh : unified interface for eigsy and eighe
+ svd_r : singular value decomposition for real matrices
+ svd_c : singular value decomposition for complex matrices
+ svd : unified interface for svd_r and svd_c
+
+
+low level routines:
+
+ r_sy_tridiag : reduction of real symmetric matrix to real symmetric tridiagonal matrix
+ c_he_tridiag_0 : reduction of complex hermitian matrix to real symmetric tridiagonal matrix
+ c_he_tridiag_1 : auxiliary routine to c_he_tridiag_0
+ c_he_tridiag_2 : auxiliary routine to c_he_tridiag_0
+ tridiag_eigen : solves the real symmetric tridiagonal matrix eigenvalue problem
+ svd_r_raw : raw singular value decomposition for real matrices
+ svd_c_raw : raw singular value decomposition for complex matrices
+"""
+
+from ..libmp.backend import xrange
+from .eigen import defun
+
+
+def r_sy_tridiag(ctx, A, D, E, calc_ev = True):
+ """
+ This routine transforms a real symmetric matrix A to a real symmetric
+ tridiagonal matrix T using an orthogonal similarity transformation:
+ Q' * A * Q = T (here ' denotes the matrix transpose).
+ The orthogonal matrix Q is build up from Householder reflectors.
+
+ parameters:
+ A (input/output) On input, A contains the real symmetric matrix of
+ dimension (n,n). On output, if calc_ev is true, A contains the
+ orthogonal matrix Q, otherwise A is destroyed.
+
+ D (output) real array of length n, contains the diagonal elements
+ of the tridiagonal matrix
+
+ E (output) real array of length n, contains the offdiagonal elements
+ of the tridiagonal matrix in E[0:(n-1)] where is the dimension of
+ the matrix A. E[n-1] is undefined.
+
+ calc_ev (input) If calc_ev is true, this routine explicitly calculates the
+ orthogonal matrix Q which is then returned in A. If calc_ev is
+ false, Q is not explicitly calculated resulting in a shorter run time.
+
+ This routine is a python translation of the fortran routine tred2.f in the
+ software library EISPACK (see netlib.org) which itself is based on the algol
+ procedure tred2 described in:
+ - Num. Math. 11, p.181-195 (1968) by Martin, Reinsch and Wilkonson
+ - Handbook for auto. comp., Vol II, Linear Algebra, p.212-226 (1971)
+
+ For a good introduction to Householder reflections, see also
+ Stoer, Bulirsch - Introduction to Numerical Analysis.
+ """
+
+ # note : the vector v of the i-th houshoulder reflector is stored in a[(i+1):,i]
+ # whereas v/ is stored in a[i,(i+1):]
+
+ n = A.rows
+ for i in xrange(n - 1, 0, -1):
+ # scale the vector
+
+ scale = 0
+ for k in xrange(0, i):
+ scale += abs(A[k,i])
+
+ scale_inv = 0
+ if scale != 0:
+ scale_inv = 1/scale
+
+ # sadly there are floating point numbers not equal to zero whose reciprocal is infinity
+
+ if i == 1 or scale == 0 or ctx.isinf(scale_inv):
+ E[i] = A[i-1,i] # nothing to do
+ D[i] = 0
+ continue
+
+ # calculate parameters for housholder transformation
+
+ H = 0
+ for k in xrange(0, i):
+ A[k,i] *= scale_inv
+ H += A[k,i] * A[k,i]
+
+ F = A[i-1,i]
+ G = ctx.sqrt(H)
+ if F > 0:
+ G = -G
+ E[i] = scale * G
+ H -= F * G
+ A[i-1,i] = F - G
+ F = 0
+
+ # apply housholder transformation
+
+ for j in xrange(0, i):
+ if calc_ev:
+ A[i,j] = A[j,i] / H
+
+ G = 0 # calculate A*U
+ for k in xrange(0, j + 1):
+ G += A[k,j] * A[k,i]
+ for k in xrange(j + 1, i):
+ G += A[j,k] * A[k,i]
+
+ E[j] = G / H # calculate P
+ F += E[j] * A[j,i]
+
+ HH = F / (2 * H)
+
+ for j in xrange(0, i): # calculate reduced A
+ F = A[j,i]
+ G = E[j] - HH * F # calculate Q
+ E[j] = G
+
+ for k in xrange(0, j + 1):
+ A[k,j] -= F * E[k] + G * A[k,i]
+
+ D[i] = H
+
+ for i in xrange(1, n): # better for compatibility
+ E[i-1] = E[i]
+ E[n-1] = 0
+
+ if calc_ev:
+ D[0] = 0
+ for i in xrange(0, n):
+ if D[i] != 0:
+ for j in xrange(0, i): # accumulate transformation matrices
+ G = 0
+ for k in xrange(0, i):
+ G += A[i,k] * A[k,j]
+ for k in xrange(0, i):
+ A[k,j] -= G * A[k,i]
+
+ D[i] = A[i,i]
+ A[i,i] = 1
+
+ for j in xrange(0, i):
+ A[j,i] = A[i,j] = 0
+ else:
+ for i in xrange(0, n):
+ D[i] = A[i,i]
+
+
+
+
+
+def c_he_tridiag_0(ctx, A, D, E, T):
+ """
+ This routine transforms a complex hermitian matrix A to a real symmetric
+ tridiagonal matrix T using an unitary similarity transformation:
+ Q' * A * Q = T (here ' denotes the hermitian matrix transpose,
+ i.e. transposition und conjugation).
+ The unitary matrix Q is build up from Householder reflectors and
+ an unitary diagonal matrix.
+
+ parameters:
+ A (input/output) On input, A contains the complex hermitian matrix
+ of dimension (n,n). On output, A contains the unitary matrix Q
+ in compressed form.
+
+ D (output) real array of length n, contains the diagonal elements
+ of the tridiagonal matrix.
+
+ E (output) real array of length n, contains the offdiagonal elements
+ of the tridiagonal matrix in E[0:(n-1)] where is the dimension of
+ the matrix A. E[n-1] is undefined.
+
+ T (output) complex array of length n, contains a unitary diagonal
+ matrix.
+
+ This routine is a python translation (in slightly modified form) of the fortran
+ routine htridi.f in the software library EISPACK (see netlib.org) which itself
+ is a complex version of the algol procedure tred1 described in:
+ - Num. Math. 11, p.181-195 (1968) by Martin, Reinsch and Wilkonson
+ - Handbook for auto. comp., Vol II, Linear Algebra, p.212-226 (1971)
+
+ For a good introduction to Householder reflections, see also
+ Stoer, Bulirsch - Introduction to Numerical Analysis.
+ """
+
+ n = A.rows
+ T[n-1] = 1
+ for i in xrange(n - 1, 0, -1):
+
+ # scale the vector
+
+ scale = 0
+ for k in xrange(0, i):
+ scale += abs(ctx.re(A[k,i])) + abs(ctx.im(A[k,i]))
+
+ scale_inv = 0
+ if scale != 0:
+ scale_inv = 1 / scale
+
+ # sadly there are floating point numbers not equal to zero whose reciprocal is infinity
+
+ if scale == 0 or ctx.isinf(scale_inv):
+ E[i] = 0
+ D[i] = 0
+ T[i-1] = 1
+ continue
+
+ if i == 1:
+ F = A[i-1,i]
+ f = abs(F)
+ E[i] = f
+ D[i] = 0
+ if f != 0:
+ T[i-1] = T[i] * F / f
+ else:
+ T[i-1] = T[i]
+ continue
+
+ # calculate parameters for housholder transformation
+
+ H = 0
+ for k in xrange(0, i):
+ A[k,i] *= scale_inv
+ rr = ctx.re(A[k,i])
+ ii = ctx.im(A[k,i])
+ H += rr * rr + ii * ii
+
+ F = A[i-1,i]
+ f = abs(F)
+ G = ctx.sqrt(H)
+ H += G * f
+ E[i] = scale * G
+ if f != 0:
+ F = F / f
+ TZ = - T[i] * F # T[i-1]=-T[i]*F, but we need T[i-1] as temporary storage
+ G *= F
+ else:
+ TZ = -T[i] # T[i-1]=-T[i]
+ A[i-1,i] += G
+ F = 0
+
+ # apply housholder transformation
+
+ for j in xrange(0, i):
+ A[i,j] = A[j,i] / H
+
+ G = 0 # calculate A*U
+ for k in xrange(0, j + 1):
+ G += ctx.conj(A[k,j]) * A[k,i]
+ for k in xrange(j + 1, i):
+ G += A[j,k] * A[k,i]
+
+ T[j] = G / H # calculate P
+ F += ctx.conj(T[j]) * A[j,i]
+
+ HH = F / (2 * H)
+
+ for j in xrange(0, i): # calculate reduced A
+ F = A[j,i]
+ G = T[j] - HH * F # calculate Q
+ T[j] = G
+
+ for k in xrange(0, j + 1):
+ A[k,j] -= ctx.conj(F) * T[k] + ctx.conj(G) * A[k,i]
+ # as we use the lower left part for storage
+ # we have to use the transpose of the normal formula
+
+ T[i-1] = TZ
+ D[i] = H
+
+ for i in xrange(1, n): # better for compatibility
+ E[i-1] = E[i]
+ E[n-1] = 0
+
+ D[0] = 0
+ for i in xrange(0, n):
+ zw = D[i]
+ D[i] = ctx.re(A[i,i])
+ A[i,i] = zw
+
+
+
+
+
+
+
+def c_he_tridiag_1(ctx, A, T):
+ """
+ This routine forms the unitary matrix Q described in c_he_tridiag_0.
+
+ parameters:
+ A (input/output) On input, A is the same matrix as delivered by
+ c_he_tridiag_0. On output, A is set to Q.
+
+ T (input) On input, T is the same array as delivered by c_he_tridiag_0.
+
+ """
+
+ n = A.rows
+
+ for i in xrange(0, n):
+ if A[i,i] != 0:
+ for j in xrange(0, i):
+ G = 0
+ for k in xrange(0, i):
+ G += ctx.conj(A[i,k]) * A[k,j]
+ for k in xrange(0, i):
+ A[k,j] -= G * A[k,i]
+
+ A[i,i] = 1
+
+ for j in xrange(0, i):
+ A[j,i] = A[i,j] = 0
+
+ for i in xrange(0, n):
+ for k in xrange(0, n):
+ A[i,k] *= T[k]
+
+
+
+
+def c_he_tridiag_2(ctx, A, T, B):
+ """
+ This routine applied the unitary matrix Q described in c_he_tridiag_0
+ onto the the matrix B, i.e. it forms Q*B.
+
+ parameters:
+ A (input) On input, A is the same matrix as delivered by c_he_tridiag_0.
+
+ T (input) On input, T is the same array as delivered by c_he_tridiag_0.
+
+ B (input/output) On input, B is a complex matrix. On output B is replaced
+ by Q*B.
+
+ This routine is a python translation of the fortran routine htribk.f in the
+ software library EISPACK (see netlib.org). See c_he_tridiag_0 for more
+ references.
+ """
+
+ n = A.rows
+
+ for i in xrange(0, n):
+ for k in xrange(0, n):
+ B[k,i] *= T[k]
+
+ for i in xrange(0, n):
+ if A[i,i] != 0:
+ for j in xrange(0, n):
+ G = 0
+ for k in xrange(0, i):
+ G += ctx.conj(A[i,k]) * B[k,j]
+ for k in xrange(0, i):
+ B[k,j] -= G * A[k,i]
+
+
+
+
+
+def tridiag_eigen(ctx, d, e, z = False):
+ """
+ This subroutine find the eigenvalues and the first components of the
+ eigenvectors of a real symmetric tridiagonal matrix using the implicit
+ QL method.
+
+ parameters:
+
+ d (input/output) real array of length n. on input, d contains the diagonal
+ elements of the input matrix. on output, d contains the eigenvalues in
+ ascending order.
+
+ e (input) real array of length n. on input, e contains the offdiagonal
+ elements of the input matrix in e[0:(n-1)]. On output, e has been
+ destroyed.
+
+ z (input/output) If z is equal to False, no eigenvectors will be computed.
+ Otherwise on input z should have the format z[0:m,0:n] (i.e. a real or
+ complex matrix of dimension (m,n) ). On output this matrix will be
+ multiplied by the matrix of the eigenvectors (i.e. the columns of this
+ matrix are the eigenvectors): z --> z*EV
+ That means if z[i,j]={1 if j==j; 0 otherwise} on input, then on output
+ z will contain the first m components of the eigenvectors. That means
+ if m is equal to n, the i-th eigenvector will be z[:,i].
+
+ This routine is a python translation (in slightly modified form) of the
+ fortran routine imtql2.f in the software library EISPACK (see netlib.org)
+ which itself is based on the algol procudure imtql2 desribed in:
+ - num. math. 12, p. 377-383(1968) by matrin and wilkinson
+ - modified in num. math. 15, p. 450(1970) by dubrulle
+ - handbook for auto. comp., vol. II-linear algebra, p. 241-248 (1971)
+ See also the routine gaussq.f in netlog.org or acm algorithm 726.
+ """
+
+ n = len(d)
+ e[n-1] = 0
+ iterlim = 2 * ctx.dps
+
+ for l in xrange(n):
+ j = 0
+ while 1:
+ m = l
+ while 1:
+ # look for a small subdiagonal element
+ if m + 1 == n:
+ break
+ if abs(e[m]) <= ctx.eps * (abs(d[m]) + abs(d[m + 1])):
+ break
+ m = m + 1
+ if m == l:
+ break
+
+ if j >= iterlim:
+ raise RuntimeError("tridiag_eigen: no convergence to an eigenvalue after %d iterations" % iterlim)
+
+ j += 1
+
+ # form shift
+
+ p = d[l]
+ g = (d[l + 1] - p) / (2 * e[l])
+ r = ctx.hypot(g, 1)
+
+ if g < 0:
+ s = g - r
+ else:
+ s = g + r
+
+ g = d[m] - p + e[l] / s
+
+ s, c, p = 1, 1, 0
+
+ for i in xrange(m - 1, l - 1, -1):
+ f = s * e[i]
+ b = c * e[i]
+ if abs(f) > abs(g): # this here is a slight improvement also used in gaussq.f or acm algorithm 726.
+ c = g / f
+ r = ctx.hypot(c, 1)
+ e[i + 1] = f * r
+ s = 1 / r
+ c = c * s
+ else:
+ s = f / g
+ r = ctx.hypot(s, 1)
+ e[i + 1] = g * r
+ c = 1 / r
+ s = s * c
+ g = d[i + 1] - p
+ r = (d[i] - g) * s + 2 * c * b
+ p = s * r
+ d[i + 1] = g + p
+ g = c * r - b
+
+ if not isinstance(z, bool):
+ # calculate eigenvectors
+ for w in xrange(z.rows):
+ f = z[w,i+1]
+ z[w,i+1] = s * z[w,i] + c * f
+ z[w,i ] = c * z[w,i] - s * f
+
+ d[l] = d[l] - p
+ e[l] = g
+ e[m] = 0
+
+ for ii in xrange(1, n):
+ # sort eigenvalues and eigenvectors (bubble-sort)
+ i = ii - 1
+ k = i
+ p = d[i]
+ for j in xrange(ii, n):
+ if d[j] >= p:
+ continue
+ k = j
+ p = d[k]
+ if k == i:
+ continue
+ d[k] = d[i]
+ d[i] = p
+
+ if not isinstance(z, bool):
+ for w in xrange(z.rows):
+ p = z[w,i]
+ z[w,i] = z[w,k]
+ z[w,k] = p
+
+########################################################################################
+
+@defun
+def eigsy(ctx, A, eigvals_only = False, overwrite_a = False):
+ """
+ This routine solves the (ordinary) eigenvalue problem for a real symmetric
+ square matrix A. Given A, an orthogonal matrix Q is calculated which
+ diagonalizes A:
+
+ Q' A Q = diag(E) and Q Q' = Q' Q = 1
+
+ Here diag(E) is a diagonal matrix whose diagonal is E.
+ ' denotes the transpose.
+
+ The columns of Q are the eigenvectors of A and E contains the eigenvalues:
+
+ A Q[:,i] = E[i] Q[:,i]
+
+
+ input:
+
+ A: real matrix of format (n,n) which is symmetric
+ (i.e. A=A' or A[i,j]=A[j,i])
+
+ eigvals_only: if true, calculates only the eigenvalues E.
+ if false, calculates both eigenvectors and eigenvalues.
+
+ overwrite_a: if true, allows modification of A which may improve
+ performance. if false, A is not modified.
+
+ output:
+
+ E: vector of format (n). contains the eigenvalues of A in ascending order.
+
+ Q: orthogonal matrix of format (n,n). contains the eigenvectors
+ of A as columns.
+
+ return value:
+
+ E if eigvals_only is true
+ (E, Q) if eigvals_only is false
+
+ example:
+ >>> from mpmath import mp
+ >>> A = mp.matrix([[3, 2], [2, 0]])
+ >>> E = mp.eigsy(A, eigvals_only = True)
+ >>> print(E)
+ [-1.0]
+ [ 4.0]
+
+ >>> A = mp.matrix([[1, 2], [2, 3]])
+ >>> E, Q = mp.eigsy(A)
+ >>> print(mp.chop(A * Q[:,0] - E[0] * Q[:,0]))
+ [0.0]
+ [0.0]
+
+ see also: eighe, eigh, eig
+ """
+
+ if not overwrite_a:
+ A = A.copy()
+
+ d = ctx.zeros(A.rows, 1)
+ e = ctx.zeros(A.rows, 1)
+
+ if eigvals_only:
+ r_sy_tridiag(ctx, A, d, e, calc_ev = False)
+ tridiag_eigen(ctx, d, e, False)
+ return d
+ else:
+ r_sy_tridiag(ctx, A, d, e, calc_ev = True)
+ tridiag_eigen(ctx, d, e, A)
+ return (d, A)
+
+
+@defun
+def eighe(ctx, A, eigvals_only = False, overwrite_a = False):
+ """
+ This routine solves the (ordinary) eigenvalue problem for a complex
+ hermitian square matrix A. Given A, an unitary matrix Q is calculated which
+ diagonalizes A:
+
+ Q' A Q = diag(E) and Q Q' = Q' Q = 1
+
+ Here diag(E) a is diagonal matrix whose diagonal is E.
+ ' denotes the hermitian transpose (i.e. ordinary transposition and
+ complex conjugation).
+
+ The columns of Q are the eigenvectors of A and E contains the eigenvalues:
+
+ A Q[:,i] = E[i] Q[:,i]
+
+
+ input:
+
+ A: complex matrix of format (n,n) which is hermitian
+ (i.e. A=A' or A[i,j]=conj(A[j,i]))
+
+ eigvals_only: if true, calculates only the eigenvalues E.
+ if false, calculates both eigenvectors and eigenvalues.
+
+ overwrite_a: if true, allows modification of A which may improve
+ performance. if false, A is not modified.
+
+ output:
+
+ E: vector of format (n). contains the eigenvalues of A in ascending order.
+
+ Q: unitary matrix of format (n,n). contains the eigenvectors
+ of A as columns.
+
+ return value:
+
+ E if eigvals_only is true
+ (E, Q) if eigvals_only is false
+
+ example:
+ >>> from mpmath import mp
+ >>> A = mp.matrix([[1, -3 - 1j], [-3 + 1j, -2]])
+ >>> E = mp.eighe(A, eigvals_only = True)
+ >>> print(E)
+ [-4.0]
+ [ 3.0]
+
+ >>> A = mp.matrix([[1, 2 + 5j], [2 - 5j, 3]])
+ >>> E, Q = mp.eighe(A)
+ >>> print(mp.chop(A * Q[:,0] - E[0] * Q[:,0]))
+ [0.0]
+ [0.0]
+
+ see also: eigsy, eigh, eig
+ """
+
+ if not overwrite_a:
+ A = A.copy()
+
+ d = ctx.zeros(A.rows, 1)
+ e = ctx.zeros(A.rows, 1)
+ t = ctx.zeros(A.rows, 1)
+
+ if eigvals_only:
+ c_he_tridiag_0(ctx, A, d, e, t)
+ tridiag_eigen(ctx, d, e, False)
+ return d
+ else:
+ c_he_tridiag_0(ctx, A, d, e, t)
+ B = ctx.eye(A.rows)
+ tridiag_eigen(ctx, d, e, B)
+ c_he_tridiag_2(ctx, A, t, B)
+ return (d, B)
+
+@defun
+def eigh(ctx, A, eigvals_only = False, overwrite_a = False):
+ """
+ "eigh" is a unified interface for "eigsy" and "eighe". Depending on
+ whether A is real or complex the appropriate function is called.
+
+ This routine solves the (ordinary) eigenvalue problem for a real symmetric
+ or complex hermitian square matrix A. Given A, an orthogonal (A real) or
+ unitary (A complex) matrix Q is calculated which diagonalizes A:
+
+ Q' A Q = diag(E) and Q Q' = Q' Q = 1
+
+ Here diag(E) a is diagonal matrix whose diagonal is E.
+ ' denotes the hermitian transpose (i.e. ordinary transposition and
+ complex conjugation).
+
+ The columns of Q are the eigenvectors of A and E contains the eigenvalues:
+
+ A Q[:,i] = E[i] Q[:,i]
+
+ input:
+
+ A: a real or complex square matrix of format (n,n) which is symmetric
+ (i.e. A[i,j]=A[j,i]) or hermitian (i.e. A[i,j]=conj(A[j,i])).
+
+ eigvals_only: if true, calculates only the eigenvalues E.
+ if false, calculates both eigenvectors and eigenvalues.
+
+ overwrite_a: if true, allows modification of A which may improve
+ performance. if false, A is not modified.
+
+ output:
+
+ E: vector of format (n). contains the eigenvalues of A in ascending order.
+
+ Q: an orthogonal or unitary matrix of format (n,n). contains the
+ eigenvectors of A as columns.
+
+ return value:
+
+ E if eigvals_only is true
+ (E, Q) if eigvals_only is false
+
+ example:
+ >>> from mpmath import mp
+ >>> A = mp.matrix([[3, 2], [2, 0]])
+ >>> E = mp.eigh(A, eigvals_only = True)
+ >>> print(E)
+ [-1.0]
+ [ 4.0]
+
+ >>> A = mp.matrix([[1, 2], [2, 3]])
+ >>> E, Q = mp.eigh(A)
+ >>> print(mp.chop(A * Q[:,0] - E[0] * Q[:,0]))
+ [0.0]
+ [0.0]
+
+ >>> A = mp.matrix([[1, 2 + 5j], [2 - 5j, 3]])
+ >>> E, Q = mp.eigh(A)
+ >>> print(mp.chop(A * Q[:,0] - E[0] * Q[:,0]))
+ [0.0]
+ [0.0]
+
+ see also: eigsy, eighe, eig
+ """
+
+ iscomplex = any(type(x) is ctx.mpc for x in A)
+
+ if iscomplex:
+ return ctx.eighe(A, eigvals_only = eigvals_only, overwrite_a = overwrite_a)
+ else:
+ return ctx.eigsy(A, eigvals_only = eigvals_only, overwrite_a = overwrite_a)
+
+
+@defun
+def gauss_quadrature(ctx, n, qtype = "legendre", alpha = 0, beta = 0):
+ """
+ This routine calulates gaussian quadrature rules for different
+ families of orthogonal polynomials. Let (a, b) be an interval,
+ W(x) a positive weight function and n a positive integer.
+ Then the purpose of this routine is to calculate pairs (x_k, w_k)
+ for k=0, 1, 2, ... (n-1) which give
+
+ int(W(x) * F(x), x = a..b) = sum(w_k * F(x_k),k = 0..(n-1))
+
+ exact for all polynomials F(x) of degree (strictly) less than 2*n. For all
+ integrable functions F(x) the sum is a (more or less) good approximation to
+ the integral. The x_k are called nodes (which are the zeros of the
+ related orthogonal polynomials) and the w_k are called the weights.
+
+ parameters
+ n (input) The degree of the quadrature rule, i.e. its number of
+ nodes.
+
+ qtype (input) The family of orthogonal polynmomials for which to
+ compute the quadrature rule. See the list below.
+
+ alpha (input) real number, used as parameter for some orthogonal
+ polynomials
+
+ beta (input) real number, used as parameter for some orthogonal
+ polynomials.
+
+ return value
+
+ (X, W) a pair of two real arrays where x_k = X[k] and w_k = W[k].
+
+
+ orthogonal polynomials:
+
+ qtype polynomial
+ ----- ----------
+
+ "legendre" Legendre polynomials, W(x)=1 on the interval (-1, +1)
+ "legendre01" shifted Legendre polynomials, W(x)=1 on the interval (0, +1)
+ "hermite" Hermite polynomials, W(x)=exp(-x*x) on (-infinity,+infinity)
+ "laguerre" Laguerre polynomials, W(x)=exp(-x) on (0,+infinity)
+ "glaguerre" generalized Laguerre polynomials, W(x)=exp(-x)*x**alpha
+ on (0, +infinity)
+ "chebyshev1" Chebyshev polynomials of the first kind, W(x)=1/sqrt(1-x*x)
+ on (-1, +1)
+ "chebyshev2" Chebyshev polynomials of the second kind, W(x)=sqrt(1-x*x)
+ on (-1, +1)
+ "jacobi" Jacobi polynomials, W(x)=(1-x)**alpha * (1+x)**beta on (-1, +1)
+ with alpha>-1 and beta>-1
+
+ examples:
+ >>> from mpmath import mp
+ >>> f = lambda x: x**8 + 2 * x**6 - 3 * x**4 + 5 * x**2 - 7
+ >>> X, W = mp.gauss_quadrature(5, "hermite")
+ >>> A = mp.fdot([(f(x), w) for x, w in zip(X, W)])
+ >>> B = mp.sqrt(mp.pi) * 57 / 16
+ >>> C = mp.quad(lambda x: mp.exp(- x * x) * f(x), [-mp.inf, +mp.inf])
+ >>> mp.nprint((mp.chop(A-B, tol = 1e-10), mp.chop(A-C, tol = 1e-10)))
+ (0.0, 0.0)
+
+ >>> f = lambda x: x**5 - 2 * x**4 + 3 * x**3 - 5 * x**2 + 7 * x - 11
+ >>> X, W = mp.gauss_quadrature(3, "laguerre")
+ >>> A = mp.fdot([(f(x), w) for x, w in zip(X, W)])
+ >>> B = 76
+ >>> C = mp.quad(lambda x: mp.exp(-x) * f(x), [0, +mp.inf])
+ >>> mp.nprint(mp.chop(A-B, tol = 1e-10), mp.chop(A-C, tol = 1e-10))
+ .0
+
+ # orthogonality of the chebyshev polynomials:
+ >>> f = lambda x: mp.chebyt(3, x) * mp.chebyt(2, x)
+ >>> X, W = mp.gauss_quadrature(3, "chebyshev1")
+ >>> A = mp.fdot([(f(x), w) for x, w in zip(X, W)])
+ >>> print(mp.chop(A, tol = 1e-10))
+ 0.0
+
+ references:
+ - golub and welsch, "calculations of gaussian quadrature rules", mathematics of
+ computation 23, p. 221-230 (1969)
+ - golub, "some modified matrix eigenvalue problems", siam review 15, p. 318-334 (1973)
+ - stroud and secrest, "gaussian quadrature formulas", prentice-hall (1966)
+
+ See also the routine gaussq.f in netlog.org or ACM Transactions on
+ Mathematical Software algorithm 726.
+ """
+
+ d = ctx.zeros(n, 1)
+ e = ctx.zeros(n, 1)
+ z = ctx.zeros(1, n)
+
+ z[0,0] = 1
+
+ if qtype == "legendre":
+ # legendre on the range -1 +1 , abramowitz, table 25.4, p.916
+ w = 2
+ for i in xrange(n):
+ j = i + 1
+ e[i] = ctx.sqrt(j * j / (4 * j * j - ctx.mpf(1)))
+ elif qtype == "legendre01":
+ # legendre shifted to 0 1 , abramowitz, table 25.8, p.921
+ w = 1
+ for i in xrange(n):
+ d[i] = 1 / ctx.mpf(2)
+ j = i + 1
+ e[i] = ctx.sqrt(j * j / (16 * j * j - ctx.mpf(4)))
+ elif qtype == "hermite":
+ # hermite on the range -inf +inf , abramowitz, table 25.10,p.924
+ w = ctx.sqrt(ctx.pi)
+ for i in xrange(n):
+ j = i + 1
+ e[i] = ctx.sqrt(j / ctx.mpf(2))
+ elif qtype == "laguerre":
+ # laguerre on the range 0 +inf , abramowitz, table 25.9, p. 923
+ w = 1
+ for i in xrange(n):
+ j = i + 1
+ d[i] = 2 * j - 1
+ e[i] = j
+ elif qtype=="chebyshev1":
+ # chebyshev polynimials of the first kind
+ w = ctx.pi
+ for i in xrange(n):
+ e[i] = 1 / ctx.mpf(2)
+ e[0] = ctx.sqrt(1 / ctx.mpf(2))
+ elif qtype == "chebyshev2":
+ # chebyshev polynimials of the second kind
+ w = ctx.pi / 2
+ for i in xrange(n):
+ e[i] = 1 / ctx.mpf(2)
+ elif qtype == "glaguerre":
+ # generalized laguerre on the range 0 +inf
+ w = ctx.gamma(1 + alpha)
+ for i in xrange(n):
+ j = i + 1
+ d[i] = 2 * j - 1 + alpha
+ e[i] = ctx.sqrt(j * (j + alpha))
+ elif qtype == "jacobi":
+ # jacobi polynomials
+ alpha = ctx.mpf(alpha)
+ beta = ctx.mpf(beta)
+ ab = alpha + beta
+ abi = ab + 2
+ w = (2**(ab+1)) * ctx.gamma(alpha + 1) * ctx.gamma(beta + 1) / ctx.gamma(abi)
+ d[0] = (beta - alpha) / abi
+ e[0] = ctx.sqrt(4 * (1 + alpha) * (1 + beta) / ((abi + 1) * (abi * abi)))
+ a2b2 = beta * beta - alpha * alpha
+ for i in xrange(1, n):
+ j = i + 1
+ abi = 2 * j + ab
+ d[i] = a2b2 / ((abi - 2) * abi)
+ e[i] = ctx.sqrt(4 * j * (j + alpha) * (j + beta) * (j + ab) / ((abi * abi - 1) * abi * abi))
+ elif isinstance(qtype, str):
+ raise ValueError("unknown quadrature rule \"%s\"" % qtype)
+ elif not isinstance(qtype, str):
+ w = qtype(d, e)
+ else:
+ assert 0
+
+ tridiag_eigen(ctx, d, e, z)
+
+ for i in xrange(len(z)):
+ z[i] *= z[i]
+
+ z = z.transpose()
+ return (d, w * z)
+
+##################################################################################################
+##################################################################################################
+##################################################################################################
+
+def svd_r_raw(ctx, A, V = False, calc_u = False):
+ """
+ This routine computes the singular value decomposition of a matrix A.
+ Given A, two orthogonal matrices U and V are calculated such that
+
+ A = U S V
+
+ where S is a suitable shaped matrix whose off-diagonal elements are zero.
+ The diagonal elements of S are the singular values of A, i.e. the
+ squareroots of the eigenvalues of A' A or A A'. Here ' denotes the transpose.
+ Householder bidiagonalization and a variant of the QR algorithm is used.
+
+ overview of the matrices :
+
+ A : m*n A gets replaced by U
+ U : m*n U replaces A. If n>m then only the first m*m block of U is
+ non-zero. column-orthogonal: U' U = B
+ here B is a n*n matrix whose first min(m,n) diagonal
+ elements are 1 and all other elements are zero.
+ S : n*n diagonal matrix, only the diagonal elements are stored in
+ the array S. only the first min(m,n) diagonal elements are non-zero.
+ V : n*n orthogonal: V V' = V' V = 1
+
+ parameters:
+ A (input/output) On input, A contains a real matrix of shape m*n.
+ On output, if calc_u is true A contains the column-orthogonal
+ matrix U; otherwise A is simply used as workspace and thus destroyed.
+
+ V (input/output) if false, the matrix V is not calculated. otherwise
+ V must be a matrix of shape n*n.
+
+ calc_u (input) If true, the matrix U is calculated and replaces A.
+ if false, U is not calculated and A is simply destroyed
+
+ return value:
+ S an array of length n containing the singular values of A sorted by
+ decreasing magnitude. only the first min(m,n) elements are non-zero.
+
+ This routine is a python translation of the fortran routine svd.f in the
+ software library EISPACK (see netlib.org) which itself is based on the
+ algol procedure svd described in:
+ - num. math. 14, 403-420(1970) by golub and reinsch.
+ - wilkinson/reinsch: handbook for auto. comp., vol ii-linear algebra, 134-151(1971).
+
+ """
+
+ m, n = A.rows, A.cols
+
+ S = ctx.zeros(n, 1)
+
+ # work is a temporary array of size n
+ work = ctx.zeros(n, 1)
+
+ g = scale = anorm = 0
+ maxits = 3 * ctx.dps
+
+ for i in xrange(n): # householder reduction to bidiagonal form
+ work[i] = scale*g
+ g = s = scale = 0
+ if i < m:
+ for k in xrange(i, m):
+ scale += ctx.fabs(A[k,i])
+ if scale != 0:
+ for k in xrange(i, m):
+ A[k,i] /= scale
+ s += A[k,i] * A[k,i]
+ f = A[i,i]
+ g = -ctx.sqrt(s)
+ if f < 0:
+ g = -g
+ h = f * g - s
+ A[i,i] = f - g
+ for j in xrange(i+1, n):
+ s = 0
+ for k in xrange(i, m):
+ s += A[k,i] * A[k,j]
+ f = s / h
+ for k in xrange(i, m):
+ A[k,j] += f * A[k,i]
+ for k in xrange(i,m):
+ A[k,i] *= scale
+
+ S[i] = scale * g
+ g = s = scale = 0
+
+ if i < m and i != n - 1:
+ for k in xrange(i+1, n):
+ scale += ctx.fabs(A[i,k])
+ if scale:
+ for k in xrange(i+1, n):
+ A[i,k] /= scale
+ s += A[i,k] * A[i,k]
+ f = A[i,i+1]
+ g = -ctx.sqrt(s)
+ if f < 0:
+ g = -g
+ h = f * g - s
+ A[i,i+1] = f - g
+
+ for k in xrange(i+1, n):
+ work[k] = A[i,k] / h
+
+ for j in xrange(i+1, m):
+ s = 0
+ for k in xrange(i+1, n):
+ s += A[j,k] * A[i,k]
+ for k in xrange(i+1, n):
+ A[j,k] += s * work[k]
+
+ for k in xrange(i+1, n):
+ A[i,k] *= scale
+
+ anorm = max(anorm, ctx.fabs(S[i]) + ctx.fabs(work[i]))
+
+ if not isinstance(V, bool):
+ for i in xrange(n-2, -1, -1): # accumulation of right hand transformations
+ V[i+1,i+1] = 1
+
+ if work[i+1] != 0:
+ for j in xrange(i+1, n):
+ V[i,j] = (A[i,j] / A[i,i+1]) / work[i+1]
+ for j in xrange(i+1, n):
+ s = 0
+ for k in xrange(i+1, n):
+ s += A[i,k] * V[j,k]
+ for k in xrange(i+1, n):
+ V[j,k] += s * V[i,k]
+
+ for j in xrange(i+1, n):
+ V[j,i] = V[i,j] = 0
+
+ V[0,0] = 1
+
+ if m= maxits:
+ raise RuntimeError("svd: no convergence to an eigenvalue after %d iterations" % its)
+
+ x = S[l] # shift from bottom 2 by 2 minor
+ nm = k-1
+ y = S[nm]
+ g = work[nm]
+ h = work[k]
+ f = ((y - z) * (y + z) + (g - h) * (g + h))/(2 * h * y)
+ g = ctx.hypot(f, 1)
+ if f >= 0: f = ((x - z) * (x + z) + h * ((y / (f + g)) - h)) / x
+ else: f = ((x - z) * (x + z) + h * ((y / (f - g)) - h)) / x
+
+ c = s = 1 # next qt transformation
+
+ for j in xrange(l, nm + 1):
+ g = work[j+1]
+ y = S[j+1]
+ h = s * g
+ g = c * g
+ z = ctx.hypot(f, h)
+ work[j] = z
+ c = f / z
+ s = h / z
+ f = x * c + g * s
+ g = g * c - x * s
+ h = y * s
+ y *= c
+ if not isinstance(V, bool):
+ for jj in xrange(n):
+ x = V[j ,jj]
+ z = V[j+1,jj]
+ V[j ,jj]= x * c + z * s
+ V[j+1 ,jj]= z * c - x * s
+ z = ctx.hypot(f, h)
+ S[j] = z
+ if z != 0: # rotation can be arbitray if z=0
+ z = 1 / z
+ c = f * z
+ s = h * z
+ f = c * g + s * y
+ x = c * y - s * g
+
+ if calc_u:
+ for jj in xrange(m):
+ y = A[jj,j ]
+ z = A[jj,j+1]
+ A[jj,j ] = y * c + z * s
+ A[jj,j+1 ] = z * c - y * s
+
+ work[l] = 0
+ work[k] = f
+ S[k] = x
+
+ ##########################
+
+ # Sort singular values into decreasing order (bubble-sort)
+
+ for i in xrange(n):
+ imax = i
+ s = ctx.fabs(S[i]) # s is the current maximal element
+
+ for j in xrange(i + 1, n):
+ c = ctx.fabs(S[j])
+ if c > s:
+ s = c
+ imax = j
+
+ if imax != i:
+ # swap singular values
+
+ z = S[i]
+ S[i] = S[imax]
+ S[imax] = z
+
+ if calc_u:
+ for j in xrange(m):
+ z = A[j,i]
+ A[j,i] = A[j,imax]
+ A[j,imax] = z
+
+ if not isinstance(V, bool):
+ for j in xrange(n):
+ z = V[i,j]
+ V[i,j] = V[imax,j]
+ V[imax,j] = z
+
+ return S
+
+#######################
+
+def svd_c_raw(ctx, A, V = False, calc_u = False):
+ """
+ This routine computes the singular value decomposition of a matrix A.
+ Given A, two unitary matrices U and V are calculated such that
+
+ A = U S V
+
+ where S is a suitable shaped matrix whose off-diagonal elements are zero.
+ The diagonal elements of S are the singular values of A, i.e. the
+ squareroots of the eigenvalues of A' A or A A'. Here ' denotes the hermitian
+ transpose (i.e. transposition and conjugation). Householder bidiagonalization
+ and a variant of the QR algorithm is used.
+
+ overview of the matrices :
+
+ A : m*n A gets replaced by U
+ U : m*n U replaces A. If n>m then only the first m*m block of U is
+ non-zero. column-unitary: U' U = B
+ here B is a n*n matrix whose first min(m,n) diagonal
+ elements are 1 and all other elements are zero.
+ S : n*n diagonal matrix, only the diagonal elements are stored in
+ the array S. only the first min(m,n) diagonal elements are non-zero.
+ V : n*n unitary: V V' = V' V = 1
+
+ parameters:
+ A (input/output) On input, A contains a complex matrix of shape m*n.
+ On output, if calc_u is true A contains the column-unitary
+ matrix U; otherwise A is simply used as workspace and thus destroyed.
+
+ V (input/output) if false, the matrix V is not calculated. otherwise
+ V must be a matrix of shape n*n.
+
+ calc_u (input) If true, the matrix U is calculated and replaces A.
+ if false, U is not calculated and A is simply destroyed
+
+ return value:
+ S an array of length n containing the singular values of A sorted by
+ decreasing magnitude. only the first min(m,n) elements are non-zero.
+
+ This routine is a python translation of the fortran routine svd.f in the
+ software library EISPACK (see netlib.org) which itself is based on the
+ algol procedure svd described in:
+ - num. math. 14, 403-420(1970) by golub and reinsch.
+ - wilkinson/reinsch: handbook for auto. comp., vol ii-linear algebra, 134-151(1971).
+
+ """
+
+ m, n = A.rows, A.cols
+
+ S = ctx.zeros(n, 1)
+
+ # work is a temporary array of size n
+ work = ctx.zeros(n, 1)
+ lbeta = ctx.zeros(n, 1)
+ rbeta = ctx.zeros(n, 1)
+ dwork = ctx.zeros(n, 1)
+
+ g = scale = anorm = 0
+ maxits = 3 * ctx.dps
+
+ for i in xrange(n): # householder reduction to bidiagonal form
+ dwork[i] = scale * g # dwork are the side-diagonal elements
+ g = s = scale = 0
+ if i < m:
+ for k in xrange(i, m):
+ scale += ctx.fabs(ctx.re(A[k,i])) + ctx.fabs(ctx.im(A[k,i]))
+ if scale != 0:
+ for k in xrange(i, m):
+ A[k,i] /= scale
+ ar = ctx.re(A[k,i])
+ ai = ctx.im(A[k,i])
+ s += ar * ar + ai * ai
+ f = A[i,i]
+ g = -ctx.sqrt(s)
+ if ctx.re(f) < 0:
+ beta = -g - ctx.conj(f)
+ g = -g
+ else:
+ beta = -g + ctx.conj(f)
+ beta /= ctx.conj(beta)
+ beta += 1
+ h = 2 * (ctx.re(f) * g - s)
+ A[i,i] = f - g
+ beta /= h
+ lbeta[i] = (beta / scale) / scale
+ for j in xrange(i+1, n):
+ s = 0
+ for k in xrange(i, m):
+ s += ctx.conj(A[k,i]) * A[k,j]
+ f = beta * s
+ for k in xrange(i, m):
+ A[k,j] += f * A[k,i]
+ for k in xrange(i, m):
+ A[k,i] *= scale
+
+ S[i] = scale * g # S are the diagonal elements
+ g = s = scale = 0
+
+ if i < m and i != n - 1:
+ for k in xrange(i+1, n):
+ scale += ctx.fabs(ctx.re(A[i,k])) + ctx.fabs(ctx.im(A[i,k]))
+ if scale:
+ for k in xrange(i+1, n):
+ A[i,k] /= scale
+ ar = ctx.re(A[i,k])
+ ai = ctx.im(A[i,k])
+ s += ar * ar + ai * ai
+ f = A[i,i+1]
+ g = -ctx.sqrt(s)
+ if ctx.re(f) < 0:
+ beta = -g - ctx.conj(f)
+ g = -g
+ else:
+ beta = -g + ctx.conj(f)
+
+ beta /= ctx.conj(beta)
+ beta += 1
+
+ h = 2 * (ctx.re(f) * g - s)
+ A[i,i+1] = f - g
+
+ beta /= h
+ rbeta[i] = (beta / scale) / scale
+
+ for k in xrange(i+1, n):
+ work[k] = A[i, k]
+
+ for j in xrange(i+1, m):
+ s = 0
+ for k in xrange(i+1, n):
+ s += ctx.conj(A[i,k]) * A[j,k]
+ f = s * beta
+ for k in xrange(i+1,n):
+ A[j,k] += f * work[k]
+
+ for k in xrange(i+1, n):
+ A[i,k] *= scale
+
+ anorm = max(anorm,ctx.fabs(S[i]) + ctx.fabs(dwork[i]))
+
+ if not isinstance(V, bool):
+ for i in xrange(n-2, -1, -1): # accumulation of right hand transformations
+ V[i+1,i+1] = 1
+
+ if dwork[i+1] != 0:
+ f = ctx.conj(rbeta[i])
+ for j in xrange(i+1, n):
+ V[i,j] = A[i,j] * f
+ for j in xrange(i+1, n):
+ s = 0
+ for k in xrange(i+1, n):
+ s += ctx.conj(A[i,k]) * V[j,k]
+ for k in xrange(i+1, n):
+ V[j,k] += s * V[i,k]
+
+ for j in xrange(i+1,n):
+ V[j,i] = V[i,j] = 0
+
+ V[0,0] = 1
+
+ if m < n : minnm = m
+ else : minnm = n
+
+ if calc_u:
+ for i in xrange(minnm-1, -1, -1): # accumulation of left hand transformations
+ g = S[i]
+ for j in xrange(i+1, n):
+ A[i,j] = 0
+ if g != 0:
+ g = 1 / g
+ for j in xrange(i+1, n):
+ s = 0
+ for k in xrange(i+1, m):
+ s += ctx.conj(A[k,i]) * A[k,j]
+ f = s * ctx.conj(lbeta[i])
+ for k in xrange(i, m):
+ A[k,j] += f * A[k,i]
+ for j in xrange(i, m):
+ A[j,i] *= g
+ else:
+ for j in xrange(i, m):
+ A[j,i] = 0
+ A[i,i] += 1
+
+ for k in xrange(n-1, -1, -1):
+ # diagonalization of the bidiagonal form:
+ # loop over singular values, and over allowed itations
+
+ its = 0
+ while 1:
+ its += 1
+ flag = True
+
+ for l in xrange(k, -1, -1):
+ nm = l - 1
+
+ if ctx.fabs(dwork[l]) + anorm == anorm:
+ flag = False
+ break
+
+ if ctx.fabs(S[nm]) + anorm == anorm:
+ break
+
+ if flag:
+ c = 0
+ s = 1
+ for i in xrange(l, k+1):
+ f = s * dwork[i]
+ dwork[i] *= c
+ if ctx.fabs(f) + anorm == anorm:
+ break
+ g = S[i]
+ h = ctx.hypot(f, g)
+ S[i] = h
+ h = 1 / h
+ c = g * h
+ s = -f * h
+
+ if calc_u:
+ for j in xrange(m):
+ y = A[j,nm]
+ z = A[j,i]
+ A[j,nm]= y * c + z * s
+ A[j,i] = z * c - y * s
+
+ z = S[k]
+
+ if l == k: # convergence
+ if z < 0: # singular value is made nonnegative
+ S[k] = -z
+ if not isinstance(V, bool):
+ for j in xrange(n):
+ V[k,j] = -V[k,j]
+ break
+
+ if its >= maxits:
+ raise RuntimeError("svd: no convergence to an eigenvalue after %d iterations" % its)
+
+ x = S[l] # shift from bottom 2 by 2 minor
+ nm = k-1
+ y = S[nm]
+ g = dwork[nm]
+ h = dwork[k]
+ f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2 * h * y)
+ g = ctx.hypot(f, 1)
+ if f >=0: f = (( x - z) *( x + z) + h *((y / (f + g)) - h)) / x
+ else: f = (( x - z) *( x + z) + h *((y / (f - g)) - h)) / x
+
+ c = s = 1 # next qt transformation
+
+ for j in xrange(l, nm + 1):
+ g = dwork[j+1]
+ y = S[j+1]
+ h = s * g
+ g = c * g
+ z = ctx.hypot(f, h)
+ dwork[j] = z
+ c = f / z
+ s = h / z
+ f = x * c + g * s
+ g = g * c - x * s
+ h = y * s
+ y *= c
+ if not isinstance(V, bool):
+ for jj in xrange(n):
+ x = V[j ,jj]
+ z = V[j+1,jj]
+ V[j ,jj]= x * c + z * s
+ V[j+1,jj ]= z * c - x * s
+ z = ctx.hypot(f, h)
+ S[j] = z
+ if z != 0: # rotation can be arbitray if z=0
+ z = 1 / z
+ c = f * z
+ s = h * z
+ f = c * g + s * y
+ x = c * y - s * g
+ if calc_u:
+ for jj in xrange(m):
+ y = A[jj,j ]
+ z = A[jj,j+1]
+ A[jj,j ]= y * c + z * s
+ A[jj,j+1 ]= z * c - y * s
+
+ dwork[l] = 0
+ dwork[k] = f
+ S[k] = x
+
+ ##########################
+
+ # Sort singular values into decreasing order (bubble-sort)
+
+ for i in xrange(n):
+ imax = i
+ s = ctx.fabs(S[i]) # s is the current maximal element
+
+ for j in xrange(i + 1, n):
+ c = ctx.fabs(S[j])
+ if c > s:
+ s = c
+ imax = j
+
+ if imax != i:
+ # swap singular values
+
+ z = S[i]
+ S[i] = S[imax]
+ S[imax] = z
+
+ if calc_u:
+ for j in xrange(m):
+ z = A[j,i]
+ A[j,i] = A[j,imax]
+ A[j,imax] = z
+
+ if not isinstance(V, bool):
+ for j in xrange(n):
+ z = V[i,j]
+ V[i,j] = V[imax,j]
+ V[imax,j] = z
+
+ return S
+
+##################################################################################################
+
+@defun
+def svd_r(ctx, A, full_matrices = False, compute_uv = True, overwrite_a = False):
+ """
+ This routine computes the singular value decomposition of a matrix A.
+ Given A, two orthogonal matrices U and V are calculated such that
+
+ A = U S V and U' U = 1 and V V' = 1
+
+ where S is a suitable shaped matrix whose off-diagonal elements are zero.
+ Here ' denotes the transpose. The diagonal elements of S are the singular
+ values of A, i.e. the squareroots of the eigenvalues of A' A or A A'.
+
+ input:
+ A : a real matrix of shape (m, n)
+ full_matrices : if true, U and V are of shape (m, m) and (n, n).
+ if false, U and V are of shape (m, min(m, n)) and (min(m, n), n).
+ compute_uv : if true, U and V are calculated. if false, only S is calculated.
+ overwrite_a : if true, allows modification of A which may improve
+ performance. if false, A is not modified.
+
+ output:
+ U : an orthogonal matrix: U' U = 1. if full_matrices is true, U is of
+ shape (m, m). ortherwise it is of shape (m, min(m, n)).
+
+ S : an array of length min(m, n) containing the singular values of A sorted by
+ decreasing magnitude.
+
+ V : an orthogonal matrix: V V' = 1. if full_matrices is true, V is of
+ shape (n, n). ortherwise it is of shape (min(m, n), n).
+
+ return value:
+
+ S if compute_uv is false
+ (U, S, V) if compute_uv is true
+
+ overview of the matrices:
+
+ full_matrices true:
+ A : m*n
+ U : m*m U' U = 1
+ S as matrix : m*n
+ V : n*n V V' = 1
+
+ full_matrices false:
+ A : m*n
+ U : m*min(n,m) U' U = 1
+ S as matrix : min(m,n)*min(m,n)
+ V : min(m,n)*n V V' = 1
+
+ examples:
+
+ >>> from mpmath import mp
+ >>> A = mp.matrix([[2, -2, -1], [3, 4, -2], [-2, -2, 0]])
+ >>> S = mp.svd_r(A, compute_uv = False)
+ >>> print(S)
+ [6.0]
+ [3.0]
+ [1.0]
+
+ >>> U, S, V = mp.svd_r(A)
+ >>> print(mp.chop(A - U * mp.diag(S) * V))
+ [0.0 0.0 0.0]
+ [0.0 0.0 0.0]
+ [0.0 0.0 0.0]
+
+
+ see also: svd, svd_c
+ """
+
+ m, n = A.rows, A.cols
+
+ if not compute_uv:
+ if not overwrite_a:
+ A = A.copy()
+ S = svd_r_raw(ctx, A, V = False, calc_u = False)
+ S = S[:min(m,n)]
+ return S
+
+ if full_matrices and n < m:
+ V = ctx.zeros(m, m)
+ A0 = ctx.zeros(m, m)
+ A0[:,:n] = A
+ S = svd_r_raw(ctx, A0, V, calc_u = True)
+
+ S = S[:n]
+ V = V[:n,:n]
+
+ return (A0, S, V)
+ else:
+ if not overwrite_a:
+ A = A.copy()
+ V = ctx.zeros(n, n)
+ S = svd_r_raw(ctx, A, V, calc_u = True)
+
+ if n > m:
+ if full_matrices == False:
+ V = V[:m,:]
+
+ S = S[:m]
+ A = A[:,:m]
+
+ return (A, S, V)
+
+##############################
+
+@defun
+def svd_c(ctx, A, full_matrices = False, compute_uv = True, overwrite_a = False):
+ """
+ This routine computes the singular value decomposition of a matrix A.
+ Given A, two unitary matrices U and V are calculated such that
+
+ A = U S V and U' U = 1 and V V' = 1
+
+ where S is a suitable shaped matrix whose off-diagonal elements are zero.
+ Here ' denotes the hermitian transpose (i.e. transposition and complex
+ conjugation). The diagonal elements of S are the singular values of A,
+ i.e. the squareroots of the eigenvalues of A' A or A A'.
+
+ input:
+ A : a complex matrix of shape (m, n)
+ full_matrices : if true, U and V are of shape (m, m) and (n, n).
+ if false, U and V are of shape (m, min(m, n)) and (min(m, n), n).
+ compute_uv : if true, U and V are calculated. if false, only S is calculated.
+ overwrite_a : if true, allows modification of A which may improve
+ performance. if false, A is not modified.
+
+ output:
+ U : an unitary matrix: U' U = 1. if full_matrices is true, U is of
+ shape (m, m). ortherwise it is of shape (m, min(m, n)).
+
+ S : an array of length min(m, n) containing the singular values of A sorted by
+ decreasing magnitude.
+
+ V : an unitary matrix: V V' = 1. if full_matrices is true, V is of
+ shape (n, n). ortherwise it is of shape (min(m, n), n).
+
+ return value:
+
+ S if compute_uv is false
+ (U, S, V) if compute_uv is true
+
+ overview of the matrices:
+
+ full_matrices true:
+ A : m*n
+ U : m*m U' U = 1
+ S as matrix : m*n
+ V : n*n V V' = 1
+
+ full_matrices false:
+ A : m*n
+ U : m*min(n,m) U' U = 1
+ S as matrix : min(m,n)*min(m,n)
+ V : min(m,n)*n V V' = 1
+
+ example:
+ >>> from mpmath import mp
+ >>> A = mp.matrix([[-2j, -1-3j, -2+2j], [2-2j, -1-3j, 1], [-3+1j,-2j,0]])
+ >>> S = mp.svd_c(A, compute_uv = False)
+ >>> print(mp.chop(S - mp.matrix([mp.sqrt(34), mp.sqrt(15), mp.sqrt(6)])))
+ [0.0]
+ [0.0]
+ [0.0]
+
+ >>> U, S, V = mp.svd_c(A)
+ >>> print(mp.chop(A - U * mp.diag(S) * V))
+ [0.0 0.0 0.0]
+ [0.0 0.0 0.0]
+ [0.0 0.0 0.0]
+
+ see also: svd, svd_r
+ """
+
+ m, n = A.rows, A.cols
+
+ if not compute_uv:
+ if not overwrite_a:
+ A = A.copy()
+ S = svd_c_raw(ctx, A, V = False, calc_u = False)
+ S = S[:min(m,n)]
+ return S
+
+ if full_matrices and n < m:
+ V = ctx.zeros(m, m)
+ A0 = ctx.zeros(m, m)
+ A0[:,:n] = A
+ S = svd_c_raw(ctx, A0, V, calc_u = True)
+
+ S = S[:n]
+ V = V[:n,:n]
+
+ return (A0, S, V)
+ else:
+ if not overwrite_a:
+ A = A.copy()
+ V = ctx.zeros(n, n)
+ S = svd_c_raw(ctx, A, V, calc_u = True)
+
+ if n > m:
+ if full_matrices == False:
+ V = V[:m,:]
+
+ S = S[:m]
+ A = A[:,:m]
+
+ return (A, S, V)
+
+@defun
+def svd(ctx, A, full_matrices = False, compute_uv = True, overwrite_a = False):
+ """
+ "svd" is a unified interface for "svd_r" and "svd_c". Depending on
+ whether A is real or complex the appropriate function is called.
+
+ This routine computes the singular value decomposition of a matrix A.
+ Given A, two orthogonal (A real) or unitary (A complex) matrices U and V
+ are calculated such that
+
+ A = U S V and U' U = 1 and V V' = 1
+
+ where S is a suitable shaped matrix whose off-diagonal elements are zero.
+ Here ' denotes the hermitian transpose (i.e. transposition and complex
+ conjugation). The diagonal elements of S are the singular values of A,
+ i.e. the squareroots of the eigenvalues of A' A or A A'.
+
+ input:
+ A : a real or complex matrix of shape (m, n)
+ full_matrices : if true, U and V are of shape (m, m) and (n, n).
+ if false, U and V are of shape (m, min(m, n)) and (min(m, n), n).
+ compute_uv : if true, U and V are calculated. if false, only S is calculated.
+ overwrite_a : if true, allows modification of A which may improve
+ performance. if false, A is not modified.
+
+ output:
+ U : an orthogonal or unitary matrix: U' U = 1. if full_matrices is true, U is of
+ shape (m, m). ortherwise it is of shape (m, min(m, n)).
+
+ S : an array of length min(m, n) containing the singular values of A sorted by
+ decreasing magnitude.
+
+ V : an orthogonal or unitary matrix: V V' = 1. if full_matrices is true, V is of
+ shape (n, n). ortherwise it is of shape (min(m, n), n).
+
+ return value:
+
+ S if compute_uv is false
+ (U, S, V) if compute_uv is true
+
+ overview of the matrices:
+
+ full_matrices true:
+ A : m*n
+ U : m*m U' U = 1
+ S as matrix : m*n
+ V : n*n V V' = 1
+
+ full_matrices false:
+ A : m*n
+ U : m*min(n,m) U' U = 1
+ S as matrix : min(m,n)*min(m,n)
+ V : min(m,n)*n V V' = 1
+
+ examples:
+
+ >>> from mpmath import mp
+ >>> A = mp.matrix([[2, -2, -1], [3, 4, -2], [-2, -2, 0]])
+ >>> S = mp.svd(A, compute_uv = False)
+ >>> print(S)
+ [6.0]
+ [3.0]
+ [1.0]
+
+ >>> U, S, V = mp.svd(A)
+ >>> print(mp.chop(A - U * mp.diag(S) * V))
+ [0.0 0.0 0.0]
+ [0.0 0.0 0.0]
+ [0.0 0.0 0.0]
+
+ see also: svd_r, svd_c
+ """
+
+ iscomplex = any(type(x) is ctx.mpc for x in A)
+
+ if iscomplex:
+ return ctx.svd_c(A, full_matrices = full_matrices, compute_uv = compute_uv, overwrite_a = overwrite_a)
+ else:
+ return ctx.svd_r(A, full_matrices = full_matrices, compute_uv = compute_uv, overwrite_a = overwrite_a)
diff --git a/lib/python3.10/site-packages/mpmath/matrices/linalg.py b/lib/python3.10/site-packages/mpmath/matrices/linalg.py
new file mode 100644
index 0000000000000000000000000000000000000000..e2fe643e809822e3d05a52b73c965edb622f9af9
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/matrices/linalg.py
@@ -0,0 +1,790 @@
+"""
+Linear algebra
+--------------
+
+Linear equations
+................
+
+Basic linear algebra is implemented; you can for example solve the linear
+equation system::
+
+ x + 2*y = -10
+ 3*x + 4*y = 10
+
+using ``lu_solve``::
+
+ >>> from mpmath import *
+ >>> mp.pretty = False
+ >>> A = matrix([[1, 2], [3, 4]])
+ >>> b = matrix([-10, 10])
+ >>> x = lu_solve(A, b)
+ >>> x
+ matrix(
+ [['30.0'],
+ ['-20.0']])
+
+If you don't trust the result, use ``residual`` to calculate the residual ||A*x-b||::
+
+ >>> residual(A, x, b)
+ matrix(
+ [['3.46944695195361e-18'],
+ ['3.46944695195361e-18']])
+ >>> str(eps)
+ '2.22044604925031e-16'
+
+As you can see, the solution is quite accurate. The error is caused by the
+inaccuracy of the internal floating point arithmetic. Though, it's even smaller
+than the current machine epsilon, which basically means you can trust the
+result.
+
+If you need more speed, use NumPy, or ``fp.lu_solve`` for a floating-point computation.
+
+ >>> fp.lu_solve(A, b) # doctest: +ELLIPSIS
+ matrix(...)
+
+``lu_solve`` accepts overdetermined systems. It is usually not possible to solve
+such systems, so the residual is minimized instead. Internally this is done
+using Cholesky decomposition to compute a least squares approximation. This means
+that that ``lu_solve`` will square the errors. If you can't afford this, use
+``qr_solve`` instead. It is twice as slow but more accurate, and it calculates
+the residual automatically.
+
+
+Matrix factorization
+....................
+
+The function ``lu`` computes an explicit LU factorization of a matrix::
+
+ >>> P, L, U = lu(matrix([[0,2,3],[4,5,6],[7,8,9]]))
+ >>> print(P)
+ [0.0 0.0 1.0]
+ [1.0 0.0 0.0]
+ [0.0 1.0 0.0]
+ >>> print(L)
+ [ 1.0 0.0 0.0]
+ [ 0.0 1.0 0.0]
+ [0.571428571428571 0.214285714285714 1.0]
+ >>> print(U)
+ [7.0 8.0 9.0]
+ [0.0 2.0 3.0]
+ [0.0 0.0 0.214285714285714]
+ >>> print(P.T*L*U)
+ [0.0 2.0 3.0]
+ [4.0 5.0 6.0]
+ [7.0 8.0 9.0]
+
+Interval matrices
+-----------------
+
+Matrices may contain interval elements. This allows one to perform
+basic linear algebra operations such as matrix multiplication
+and equation solving with rigorous error bounds::
+
+ >>> 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)
+ >>> print(c)
+ [ [5.2582327113062568605927528666, 5.25823271130625686059275702219]]
+ [[-13.1550493962678375411635581388, -13.1550493962678375411635540152]]
+ [ [7.42069154774972557628979076189, 7.42069154774972557628979190734]]
+ >>> print(a*c)
+ [ [3.99999999999999999999999844904, 4.00000000000000000000000155096]]
+ [[0.599999999999999999999968898009, 0.600000000000000000000031763736]]
+ [[0.499999999999999999999979320485, 0.500000000000000000000020679515]]
+"""
+
+# TODO:
+# *implement high-level qr()
+# *test unitvector
+# *iterative solving
+
+from copy import copy
+
+from ..libmp.backend import xrange
+
+class LinearAlgebraMethods(object):
+
+ def LU_decomp(ctx, A, overwrite=False, use_cache=True):
+ """
+ LU-factorization of a n*n matrix using the Gauss algorithm.
+ Returns L and U in one matrix and the pivot indices.
+
+ Use overwrite to specify whether A will be overwritten with L and U.
+ """
+ if not A.rows == A.cols:
+ raise ValueError('need n*n matrix')
+ # get from cache if possible
+ if use_cache and isinstance(A, ctx.matrix) and A._LU:
+ return A._LU
+ if not overwrite:
+ orig = A
+ A = A.copy()
+ tol = ctx.absmin(ctx.mnorm(A,1) * ctx.eps) # each pivot element has to be bigger
+ n = A.rows
+ p = [None]*(n - 1)
+ for j in xrange(n - 1):
+ # pivoting, choose max(abs(reciprocal row sum)*abs(pivot element))
+ biggest = 0
+ for k in xrange(j, n):
+ s = ctx.fsum([ctx.absmin(A[k,l]) for l in xrange(j, n)])
+ if ctx.absmin(s) <= tol:
+ raise ZeroDivisionError('matrix is numerically singular')
+ current = 1/s * ctx.absmin(A[k,j])
+ if current > biggest: # TODO: what if equal?
+ biggest = current
+ p[j] = k
+ # swap rows according to p
+ ctx.swap_row(A, j, p[j])
+ if ctx.absmin(A[j,j]) <= tol:
+ raise ZeroDivisionError('matrix is numerically singular')
+ # calculate elimination factors and add rows
+ for i in xrange(j + 1, n):
+ A[i,j] /= A[j,j]
+ for k in xrange(j + 1, n):
+ A[i,k] -= A[i,j]*A[j,k]
+ if ctx.absmin(A[n - 1,n - 1]) <= tol:
+ raise ZeroDivisionError('matrix is numerically singular')
+ # cache decomposition
+ if not overwrite and isinstance(orig, ctx.matrix):
+ orig._LU = (A, p)
+ return A, p
+
+ def L_solve(ctx, L, b, p=None):
+ """
+ Solve the lower part of a LU factorized matrix for y.
+ """
+ if L.rows != L.cols:
+ raise RuntimeError("need n*n matrix")
+ n = L.rows
+ if len(b) != n:
+ raise ValueError("Value should be equal to n")
+ b = copy(b)
+ if p: # swap b according to p
+ for k in xrange(0, len(p)):
+ ctx.swap_row(b, k, p[k])
+ # solve
+ for i in xrange(1, n):
+ for j in xrange(i):
+ b[i] -= L[i,j] * b[j]
+ return b
+
+ def U_solve(ctx, U, y):
+ """
+ Solve the upper part of a LU factorized matrix for x.
+ """
+ if U.rows != U.cols:
+ raise RuntimeError("need n*n matrix")
+ n = U.rows
+ if len(y) != n:
+ raise ValueError("Value should be equal to n")
+ x = copy(y)
+ for i in xrange(n - 1, -1, -1):
+ for j in xrange(i + 1, n):
+ x[i] -= U[i,j] * x[j]
+ x[i] /= U[i,i]
+ return x
+
+ def lu_solve(ctx, A, b, **kwargs):
+ """
+ Ax = b => x
+
+ Solve a determined or overdetermined linear equations system.
+ Fast LU decomposition is used, which is less accurate than QR decomposition
+ (especially for overdetermined systems), but it's twice as efficient.
+ Use qr_solve if you want more precision or have to solve a very ill-
+ conditioned system.
+
+ If you specify real=True, it does not check for overdeterminded complex
+ systems.
+ """
+ prec = ctx.prec
+ try:
+ ctx.prec += 10
+ # do not overwrite A nor b
+ A, b = ctx.matrix(A, **kwargs).copy(), ctx.matrix(b, **kwargs).copy()
+ if A.rows < A.cols:
+ raise ValueError('cannot solve underdetermined system')
+ if A.rows > A.cols:
+ # use least-squares method if overdetermined
+ # (this increases errors)
+ AH = A.H
+ A = AH * A
+ b = AH * b
+ if (kwargs.get('real', False) or
+ not sum(type(i) is ctx.mpc for i in A)):
+ # TODO: necessary to check also b?
+ x = ctx.cholesky_solve(A, b)
+ else:
+ x = ctx.lu_solve(A, b)
+ else:
+ # LU factorization
+ A, p = ctx.LU_decomp(A)
+ b = ctx.L_solve(A, b, p)
+ x = ctx.U_solve(A, b)
+ finally:
+ ctx.prec = prec
+ return x
+
+ def improve_solution(ctx, A, x, b, maxsteps=1):
+ """
+ Improve a solution to a linear equation system iteratively.
+
+ This re-uses the LU decomposition and is thus cheap.
+ Usually 3 up to 4 iterations are giving the maximal improvement.
+ """
+ if A.rows != A.cols:
+ raise RuntimeError("need n*n matrix") # TODO: really?
+ for _ in xrange(maxsteps):
+ r = ctx.residual(A, x, b)
+ if ctx.norm(r, 2) < 10*ctx.eps:
+ break
+ # this uses cached LU decomposition and is thus cheap
+ dx = ctx.lu_solve(A, -r)
+ x += dx
+ return x
+
+ def lu(ctx, A):
+ """
+ A -> P, L, U
+
+ LU factorisation of a square matrix A. L is the lower, U the upper part.
+ P is the permutation matrix indicating the row swaps.
+
+ P*A = L*U
+
+ If you need efficiency, use the low-level method LU_decomp instead, it's
+ much more memory efficient.
+ """
+ # get factorization
+ A, p = ctx.LU_decomp(A)
+ n = A.rows
+ L = ctx.matrix(n)
+ U = ctx.matrix(n)
+ for i in xrange(n):
+ for j in xrange(n):
+ if i > j:
+ L[i,j] = A[i,j]
+ elif i == j:
+ L[i,j] = 1
+ U[i,j] = A[i,j]
+ else:
+ U[i,j] = A[i,j]
+ # calculate permutation matrix
+ P = ctx.eye(n)
+ for k in xrange(len(p)):
+ ctx.swap_row(P, k, p[k])
+ return P, L, U
+
+ def unitvector(ctx, n, i):
+ """
+ Return the i-th n-dimensional unit vector.
+ """
+ assert 0 < i <= n, 'this unit vector does not exist'
+ return [ctx.zero]*(i-1) + [ctx.one] + [ctx.zero]*(n-i)
+
+ def inverse(ctx, A, **kwargs):
+ """
+ Calculate the inverse of a matrix.
+
+ If you want to solve an equation system Ax = b, it's recommended to use
+ solve(A, b) instead, it's about 3 times more efficient.
+ """
+ prec = ctx.prec
+ try:
+ ctx.prec += 10
+ # do not overwrite A
+ A = ctx.matrix(A, **kwargs).copy()
+ n = A.rows
+ # get LU factorisation
+ A, p = ctx.LU_decomp(A)
+ cols = []
+ # calculate unit vectors and solve corresponding system to get columns
+ for i in xrange(1, n + 1):
+ e = ctx.unitvector(n, i)
+ y = ctx.L_solve(A, e, p)
+ cols.append(ctx.U_solve(A, y))
+ # convert columns to matrix
+ inv = []
+ for i in xrange(n):
+ row = []
+ for j in xrange(n):
+ row.append(cols[j][i])
+ inv.append(row)
+ result = ctx.matrix(inv, **kwargs)
+ finally:
+ ctx.prec = prec
+ return result
+
+ def householder(ctx, A):
+ """
+ (A|b) -> H, p, x, res
+
+ (A|b) is the coefficient matrix with left hand side of an optionally
+ overdetermined linear equation system.
+ H and p contain all information about the transformation matrices.
+ x is the solution, res the residual.
+ """
+ if not isinstance(A, ctx.matrix):
+ raise TypeError("A should be a type of ctx.matrix")
+ m = A.rows
+ n = A.cols
+ if m < n - 1:
+ raise RuntimeError("Columns should not be less than rows")
+ # calculate Householder matrix
+ p = []
+ for j in xrange(0, n - 1):
+ s = ctx.fsum(abs(A[i,j])**2 for i in xrange(j, m))
+ if not abs(s) > ctx.eps:
+ raise ValueError('matrix is numerically singular')
+ p.append(-ctx.sign(ctx.re(A[j,j])) * ctx.sqrt(s))
+ kappa = ctx.one / (s - p[j] * A[j,j])
+ A[j,j] -= p[j]
+ for k in xrange(j+1, n):
+ y = ctx.fsum(ctx.conj(A[i,j]) * A[i,k] for i in xrange(j, m)) * kappa
+ for i in xrange(j, m):
+ A[i,k] -= A[i,j] * y
+ # solve Rx = c1
+ x = [A[i,n - 1] for i in xrange(n - 1)]
+ for i in xrange(n - 2, -1, -1):
+ x[i] -= ctx.fsum(A[i,j] * x[j] for j in xrange(i + 1, n - 1))
+ x[i] /= p[i]
+ # calculate residual
+ if not m == n - 1:
+ r = [A[m-1-i, n-1] for i in xrange(m - n + 1)]
+ else:
+ # determined system, residual should be 0
+ r = [0]*m # maybe a bad idea, changing r[i] will change all elements
+ return A, p, x, r
+
+ #def qr(ctx, A):
+ # """
+ # A -> Q, R
+ #
+ # QR factorisation of a square matrix A using Householder decomposition.
+ # Q is orthogonal, this leads to very few numerical errors.
+ #
+ # A = Q*R
+ # """
+ # H, p, x, res = householder(A)
+ # TODO: implement this
+
+ def residual(ctx, A, x, b, **kwargs):
+ """
+ Calculate the residual of a solution to a linear equation system.
+
+ r = A*x - b for A*x = b
+ """
+ oldprec = ctx.prec
+ try:
+ ctx.prec *= 2
+ A, x, b = ctx.matrix(A, **kwargs), ctx.matrix(x, **kwargs), ctx.matrix(b, **kwargs)
+ return A*x - b
+ finally:
+ ctx.prec = oldprec
+
+ def qr_solve(ctx, A, b, norm=None, **kwargs):
+ """
+ Ax = b => x, ||Ax - b||
+
+ Solve a determined or overdetermined linear equations system and
+ calculate the norm of the residual (error).
+ QR decomposition using Householder factorization is applied, which gives very
+ accurate results even for ill-conditioned matrices. qr_solve is twice as
+ efficient.
+ """
+ if norm is None:
+ norm = ctx.norm
+ prec = ctx.prec
+ try:
+ ctx.prec += 10
+ # do not overwrite A nor b
+ A, b = ctx.matrix(A, **kwargs).copy(), ctx.matrix(b, **kwargs).copy()
+ if A.rows < A.cols:
+ raise ValueError('cannot solve underdetermined system')
+ H, p, x, r = ctx.householder(ctx.extend(A, b))
+ res = ctx.norm(r)
+ # calculate residual "manually" for determined systems
+ if res == 0:
+ res = ctx.norm(ctx.residual(A, x, b))
+ return ctx.matrix(x, **kwargs), res
+ finally:
+ ctx.prec = prec
+
+ def cholesky(ctx, A, tol=None):
+ r"""
+ Cholesky decomposition of a symmetric positive-definite matrix `A`.
+ Returns a lower triangular matrix `L` such that `A = L \times L^T`.
+ More generally, for a complex Hermitian positive-definite matrix,
+ a Cholesky decomposition satisfying `A = L \times L^H` is returned.
+
+ The Cholesky decomposition can be used to solve linear equation
+ systems twice as efficiently as LU decomposition, or to
+ test whether `A` is positive-definite.
+
+ The optional parameter ``tol`` determines the tolerance for
+ verifying positive-definiteness.
+
+ **Examples**
+
+ Cholesky decomposition of a positive-definite symmetric matrix::
+
+ >>> from mpmath import *
+ >>> mp.dps = 25; mp.pretty = True
+ >>> A = eye(3) + hilbert(3)
+ >>> nprint(A)
+ [ 2.0 0.5 0.333333]
+ [ 0.5 1.33333 0.25]
+ [0.333333 0.25 1.2]
+ >>> L = cholesky(A)
+ >>> nprint(L)
+ [ 1.41421 0.0 0.0]
+ [0.353553 1.09924 0.0]
+ [0.235702 0.15162 1.05899]
+ >>> chop(A - L*L.T)
+ [0.0 0.0 0.0]
+ [0.0 0.0 0.0]
+ [0.0 0.0 0.0]
+
+ Cholesky decomposition of a Hermitian matrix::
+
+ >>> A = eye(3) + matrix([[0,0.25j,-0.5j],[-0.25j,0,0],[0.5j,0,0]])
+ >>> L = cholesky(A)
+ >>> nprint(L)
+ [ 1.0 0.0 0.0]
+ [(0.0 - 0.25j) (0.968246 + 0.0j) 0.0]
+ [ (0.0 + 0.5j) (0.129099 + 0.0j) (0.856349 + 0.0j)]
+ >>> chop(A - L*L.H)
+ [0.0 0.0 0.0]
+ [0.0 0.0 0.0]
+ [0.0 0.0 0.0]
+
+ Attempted Cholesky decomposition of a matrix that is not positive
+ definite::
+
+ >>> A = -eye(3) + hilbert(3)
+ >>> L = cholesky(A)
+ Traceback (most recent call last):
+ ...
+ ValueError: matrix is not positive-definite
+
+ **References**
+
+ 1. [Wikipedia]_ http://en.wikipedia.org/wiki/Cholesky_decomposition
+
+ """
+ if not isinstance(A, ctx.matrix):
+ raise RuntimeError("A should be a type of ctx.matrix")
+ if not A.rows == A.cols:
+ raise ValueError('need n*n matrix')
+ if tol is None:
+ tol = +ctx.eps
+ n = A.rows
+ L = ctx.matrix(n)
+ for j in xrange(n):
+ c = ctx.re(A[j,j])
+ if abs(c-A[j,j]) > tol:
+ raise ValueError('matrix is not Hermitian')
+ s = c - ctx.fsum((L[j,k] for k in xrange(j)),
+ absolute=True, squared=True)
+ if s < tol:
+ raise ValueError('matrix is not positive-definite')
+ L[j,j] = ctx.sqrt(s)
+ for i in xrange(j, n):
+ it1 = (L[i,k] for k in xrange(j))
+ it2 = (L[j,k] for k in xrange(j))
+ t = ctx.fdot(it1, it2, conjugate=True)
+ L[i,j] = (A[i,j] - t) / L[j,j]
+ return L
+
+ def cholesky_solve(ctx, A, b, **kwargs):
+ """
+ Ax = b => x
+
+ Solve a symmetric positive-definite linear equation system.
+ This is twice as efficient as lu_solve.
+
+ Typical use cases:
+ * A.T*A
+ * Hessian matrix
+ * differential equations
+ """
+ prec = ctx.prec
+ try:
+ ctx.prec += 10
+ # do not overwrite A nor b
+ A, b = ctx.matrix(A, **kwargs).copy(), ctx.matrix(b, **kwargs).copy()
+ if A.rows != A.cols:
+ raise ValueError('can only solve determined system')
+ # Cholesky factorization
+ L = ctx.cholesky(A)
+ # solve
+ n = L.rows
+ if len(b) != n:
+ raise ValueError("Value should be equal to n")
+ for i in xrange(n):
+ b[i] -= ctx.fsum(L[i,j] * b[j] for j in xrange(i))
+ b[i] /= L[i,i]
+ x = ctx.U_solve(L.T, b)
+ return x
+ finally:
+ ctx.prec = prec
+
+ def det(ctx, A):
+ """
+ Calculate the determinant of a matrix.
+ """
+ prec = ctx.prec
+ try:
+ # do not overwrite A
+ A = ctx.matrix(A).copy()
+ # use LU factorization to calculate determinant
+ try:
+ R, p = ctx.LU_decomp(A)
+ except ZeroDivisionError:
+ return 0
+ z = 1
+ for i, e in enumerate(p):
+ if i != e:
+ z *= -1
+ for i in xrange(A.rows):
+ z *= R[i,i]
+ return z
+ finally:
+ ctx.prec = prec
+
+ def cond(ctx, A, norm=None):
+ """
+ Calculate the condition number of a matrix using a specified matrix norm.
+
+ The condition number estimates the sensitivity of a matrix to errors.
+ Example: small input errors for ill-conditioned coefficient matrices
+ alter the solution of the system dramatically.
+
+ For ill-conditioned matrices it's recommended to use qr_solve() instead
+ of lu_solve(). This does not help with input errors however, it just avoids
+ to add additional errors.
+
+ Definition: cond(A) = ||A|| * ||A**-1||
+ """
+ if norm is None:
+ norm = lambda x: ctx.mnorm(x,1)
+ return norm(A) * norm(ctx.inverse(A))
+
+ def lu_solve_mat(ctx, a, b):
+ """Solve a * x = b where a and b are matrices."""
+ r = ctx.matrix(a.rows, b.cols)
+ for i in range(b.cols):
+ c = ctx.lu_solve(a, b.column(i))
+ for j in range(len(c)):
+ r[j, i] = c[j]
+ return r
+
+ def qr(ctx, A, mode = 'full', edps = 10):
+ """
+ Compute a QR factorization $A = QR$ where
+ A is an m x n matrix of real or complex numbers where m >= n
+
+ mode has following meanings:
+ (1) mode = 'raw' returns two matrixes (A, tau) in the
+ internal format used by LAPACK
+ (2) mode = 'skinny' returns the leading n columns of Q
+ and n rows of R
+ (3) Any other value returns the leading m columns of Q
+ and m rows of R
+
+ edps is the increase in mp precision used for calculations
+
+ **Examples**
+
+ >>> from mpmath import *
+ >>> mp.dps = 15
+ >>> mp.pretty = True
+ >>> A = matrix([[1, 2], [3, 4], [1, 1]])
+ >>> Q, R = qr(A)
+ >>> Q
+ [-0.301511344577764 0.861640436855329 0.408248290463863]
+ [-0.904534033733291 -0.123091490979333 -0.408248290463863]
+ [-0.301511344577764 -0.492365963917331 0.816496580927726]
+ >>> R
+ [-3.3166247903554 -4.52267016866645]
+ [ 0.0 0.738548945875996]
+ [ 0.0 0.0]
+ >>> Q * R
+ [1.0 2.0]
+ [3.0 4.0]
+ [1.0 1.0]
+ >>> chop(Q.T * Q)
+ [1.0 0.0 0.0]
+ [0.0 1.0 0.0]
+ [0.0 0.0 1.0]
+ >>> B = matrix([[1+0j, 2-3j], [3+j, 4+5j]])
+ >>> Q, R = qr(B)
+ >>> nprint(Q)
+ [ (-0.301511 + 0.0j) (0.0695795 - 0.95092j)]
+ [(-0.904534 - 0.301511j) (-0.115966 + 0.278318j)]
+ >>> nprint(R)
+ [(-3.31662 + 0.0j) (-5.72872 - 2.41209j)]
+ [ 0.0 (3.91965 + 0.0j)]
+ >>> Q * R
+ [(1.0 + 0.0j) (2.0 - 3.0j)]
+ [(3.0 + 1.0j) (4.0 + 5.0j)]
+ >>> chop(Q.T * Q.conjugate())
+ [1.0 0.0]
+ [0.0 1.0]
+
+ """
+
+ # check values before continuing
+ assert isinstance(A, ctx.matrix)
+ m = A.rows
+ n = A.cols
+ assert n >= 0
+ assert m >= n
+ assert edps >= 0
+
+ # check for complex data type
+ cmplx = any(type(x) is ctx.mpc for x in A)
+
+ # temporarily increase the precision and initialize
+ with ctx.extradps(edps):
+ tau = ctx.matrix(n,1)
+ A = A.copy()
+
+ # ---------------
+ # FACTOR MATRIX A
+ # ---------------
+ if cmplx:
+ one = ctx.mpc('1.0', '0.0')
+ zero = ctx.mpc('0.0', '0.0')
+ rzero = ctx.mpf('0.0')
+
+ # main loop to factor A (complex)
+ for j in xrange(0, n):
+ alpha = A[j,j]
+ alphr = ctx.re(alpha)
+ alphi = ctx.im(alpha)
+
+ if (m-j) >= 2:
+ xnorm = ctx.fsum( A[i,j]*ctx.conj(A[i,j]) for i in xrange(j+1, m) )
+ xnorm = ctx.re( ctx.sqrt(xnorm) )
+ else:
+ xnorm = rzero
+
+ if (xnorm == rzero) and (alphi == rzero):
+ tau[j] = zero
+ continue
+
+ if alphr < rzero:
+ beta = ctx.sqrt(alphr**2 + alphi**2 + xnorm**2)
+ else:
+ beta = -ctx.sqrt(alphr**2 + alphi**2 + xnorm**2)
+
+ tau[j] = ctx.mpc( (beta - alphr) / beta, -alphi / beta )
+ t = -ctx.conj(tau[j])
+ za = one / (alpha - beta)
+
+ for i in xrange(j+1, m):
+ A[i,j] *= za
+
+ A[j,j] = one
+ for k in xrange(j+1, n):
+ y = ctx.fsum(A[i,j] * ctx.conj(A[i,k]) for i in xrange(j, m))
+ temp = t * ctx.conj(y)
+ for i in xrange(j, m):
+ A[i,k] += A[i,j] * temp
+
+ A[j,j] = ctx.mpc(beta, '0.0')
+ else:
+ one = ctx.mpf('1.0')
+ zero = ctx.mpf('0.0')
+
+ # main loop to factor A (real)
+ for j in xrange(0, n):
+ alpha = A[j,j]
+
+ if (m-j) > 2:
+ xnorm = ctx.fsum( (A[i,j])**2 for i in xrange(j+1, m) )
+ xnorm = ctx.sqrt(xnorm)
+ elif (m-j) == 2:
+ xnorm = abs( A[m-1,j] )
+ else:
+ xnorm = zero
+
+ if xnorm == zero:
+ tau[j] = zero
+ continue
+
+ if alpha < zero:
+ beta = ctx.sqrt(alpha**2 + xnorm**2)
+ else:
+ beta = -ctx.sqrt(alpha**2 + xnorm**2)
+
+ tau[j] = (beta - alpha) / beta
+ t = -tau[j]
+ da = one / (alpha - beta)
+
+ for i in xrange(j+1, m):
+ A[i,j] *= da
+
+ A[j,j] = one
+ for k in xrange(j+1, n):
+ y = ctx.fsum( A[i,j] * A[i,k] for i in xrange(j, m) )
+ temp = t * y
+ for i in xrange(j,m):
+ A[i,k] += A[i,j] * temp
+
+ A[j,j] = beta
+
+ # return factorization in same internal format as LAPACK
+ if (mode == 'raw') or (mode == 'RAW'):
+ return A, tau
+
+ # ----------------------------------
+ # FORM Q USING BACKWARD ACCUMULATION
+ # ----------------------------------
+
+ # form R before the values are overwritten
+ R = A.copy()
+ for j in xrange(0, n):
+ for i in xrange(j+1, m):
+ R[i,j] = zero
+
+ # set the value of p (number of columns of Q to return)
+ p = m
+ if (mode == 'skinny') or (mode == 'SKINNY'):
+ p = n
+
+ # add columns to A if needed and initialize
+ A.cols += (p-n)
+ for j in xrange(0, p):
+ A[j,j] = one
+ for i in xrange(0, j):
+ A[i,j] = zero
+
+ # main loop to form Q
+ for j in xrange(n-1, -1, -1):
+ t = -tau[j]
+ A[j,j] += t
+
+ for k in xrange(j+1, p):
+ if cmplx:
+ y = ctx.fsum(A[i,j] * ctx.conj(A[i,k]) for i in xrange(j+1, m))
+ temp = t * ctx.conj(y)
+ else:
+ y = ctx.fsum(A[i,j] * A[i,k] for i in xrange(j+1, m))
+ temp = t * y
+ A[j,k] = temp
+ for i in xrange(j+1, m):
+ A[i,k] += A[i,j] * temp
+
+ for i in xrange(j+1, m):
+ A[i, j] *= t
+
+ return A, R[0:p,0:n]
+
+ # ------------------
+ # END OF FUNCTION QR
+ # ------------------
diff --git a/lib/python3.10/site-packages/mpmath/matrices/matrices.py b/lib/python3.10/site-packages/mpmath/matrices/matrices.py
new file mode 100644
index 0000000000000000000000000000000000000000..a97d5a9ca7e173195386dc7cb60860a826ab6a97
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/matrices/matrices.py
@@ -0,0 +1,1005 @@
+from ..libmp.backend import xrange
+import warnings
+
+# TODO: interpret list as vectors (for multiplication)
+
+rowsep = '\n'
+colsep = ' '
+
+class _matrix(object):
+ """
+ Numerical matrix.
+
+ Specify the dimensions or the data as a nested list.
+ Elements default to zero.
+ Use a flat list to create a column vector easily.
+
+ The datatype of the context (mpf for mp, mpi for iv, and float for fp) is used to store the data.
+
+ Creating matrices
+ -----------------
+
+ Matrices in mpmath are implemented using dictionaries. Only non-zero values
+ are stored, so it is cheap to represent sparse matrices.
+
+ The most basic way to create one is to use the ``matrix`` class directly.
+ You can create an empty matrix specifying the dimensions:
+
+ >>> from mpmath import *
+ >>> mp.dps = 15
+ >>> matrix(2)
+ matrix(
+ [['0.0', '0.0'],
+ ['0.0', '0.0']])
+ >>> matrix(2, 3)
+ matrix(
+ [['0.0', '0.0', '0.0'],
+ ['0.0', '0.0', '0.0']])
+
+ Calling ``matrix`` with one dimension will create a square matrix.
+
+ To access the dimensions of a matrix, use the ``rows`` or ``cols`` keyword:
+
+ >>> A = matrix(3, 2)
+ >>> A
+ matrix(
+ [['0.0', '0.0'],
+ ['0.0', '0.0'],
+ ['0.0', '0.0']])
+ >>> A.rows
+ 3
+ >>> A.cols
+ 2
+
+ You can also change the dimension of an existing matrix. This will set the
+ new elements to 0. If the new dimension is smaller than before, the
+ concerning elements are discarded:
+
+ >>> A.rows = 2
+ >>> A
+ matrix(
+ [['0.0', '0.0'],
+ ['0.0', '0.0']])
+
+ Internally ``mpmathify`` is used every time an element is set. This
+ is done using the syntax A[row,column], counting from 0:
+
+ >>> A = matrix(2)
+ >>> A[1,1] = 1 + 1j
+ >>> A
+ matrix(
+ [['0.0', '0.0'],
+ ['0.0', mpc(real='1.0', imag='1.0')]])
+
+ A more comfortable way to create a matrix lets you use nested lists:
+
+ >>> matrix([[1, 2], [3, 4]])
+ matrix(
+ [['1.0', '2.0'],
+ ['3.0', '4.0']])
+
+ Convenient advanced functions are available for creating various standard
+ matrices, see ``zeros``, ``ones``, ``diag``, ``eye``, ``randmatrix`` and
+ ``hilbert``.
+
+ Vectors
+ .......
+
+ Vectors may also be represented by the ``matrix`` class (with rows = 1 or cols = 1).
+ For vectors there are some things which make life easier. A column vector can
+ be created using a flat list, a row vectors using an almost flat nested list::
+
+ >>> matrix([1, 2, 3])
+ matrix(
+ [['1.0'],
+ ['2.0'],
+ ['3.0']])
+ >>> matrix([[1, 2, 3]])
+ matrix(
+ [['1.0', '2.0', '3.0']])
+
+ Optionally vectors can be accessed like lists, using only a single index::
+
+ >>> x = matrix([1, 2, 3])
+ >>> x[1]
+ mpf('2.0')
+ >>> x[1,0]
+ mpf('2.0')
+
+ Other
+ .....
+
+ Like you probably expected, matrices can be printed::
+
+ >>> print randmatrix(3) # doctest:+SKIP
+ [ 0.782963853573023 0.802057689719883 0.427895717335467]
+ [0.0541876859348597 0.708243266653103 0.615134039977379]
+ [ 0.856151514955773 0.544759264818486 0.686210904770947]
+
+ Use ``nstr`` or ``nprint`` to specify the number of digits to print::
+
+ >>> nprint(randmatrix(5), 3) # doctest:+SKIP
+ [2.07e-1 1.66e-1 5.06e-1 1.89e-1 8.29e-1]
+ [6.62e-1 6.55e-1 4.47e-1 4.82e-1 2.06e-2]
+ [4.33e-1 7.75e-1 6.93e-2 2.86e-1 5.71e-1]
+ [1.01e-1 2.53e-1 6.13e-1 3.32e-1 2.59e-1]
+ [1.56e-1 7.27e-2 6.05e-1 6.67e-2 2.79e-1]
+
+ As matrices are mutable, you will need to copy them sometimes::
+
+ >>> A = matrix(2)
+ >>> A
+ matrix(
+ [['0.0', '0.0'],
+ ['0.0', '0.0']])
+ >>> B = A.copy()
+ >>> B[0,0] = 1
+ >>> B
+ matrix(
+ [['1.0', '0.0'],
+ ['0.0', '0.0']])
+ >>> A
+ matrix(
+ [['0.0', '0.0'],
+ ['0.0', '0.0']])
+
+ Finally, it is possible to convert a matrix to a nested list. This is very useful,
+ as most Python libraries involving matrices or arrays (namely NumPy or SymPy)
+ support this format::
+
+ >>> B.tolist()
+ [[mpf('1.0'), mpf('0.0')], [mpf('0.0'), mpf('0.0')]]
+
+
+ Matrix operations
+ -----------------
+
+ You can add and subtract matrices of compatible dimensions::
+
+ >>> A = matrix([[1, 2], [3, 4]])
+ >>> B = matrix([[-2, 4], [5, 9]])
+ >>> A + B
+ matrix(
+ [['-1.0', '6.0'],
+ ['8.0', '13.0']])
+ >>> A - B
+ matrix(
+ [['3.0', '-2.0'],
+ ['-2.0', '-5.0']])
+ >>> A + ones(3) # doctest:+ELLIPSIS
+ Traceback (most recent call last):
+ ...
+ ValueError: incompatible dimensions for addition
+
+ It is possible to multiply or add matrices and scalars. In the latter case the
+ operation will be done element-wise::
+
+ >>> A * 2
+ matrix(
+ [['2.0', '4.0'],
+ ['6.0', '8.0']])
+ >>> A / 4
+ matrix(
+ [['0.25', '0.5'],
+ ['0.75', '1.0']])
+ >>> A - 1
+ matrix(
+ [['0.0', '1.0'],
+ ['2.0', '3.0']])
+
+ Of course you can perform matrix multiplication, if the dimensions are
+ compatible, using ``@`` (for Python >= 3.5) or ``*``. For clarity, ``@`` is
+ recommended (`PEP 465 `), because
+ the meaning of ``*`` is different in many other Python libraries such as NumPy.
+
+ >>> A @ B # doctest:+SKIP
+ matrix(
+ [['8.0', '22.0'],
+ ['14.0', '48.0']])
+ >>> A * B # same as A @ B
+ matrix(
+ [['8.0', '22.0'],
+ ['14.0', '48.0']])
+ >>> matrix([[1, 2, 3]]) * matrix([[-6], [7], [-2]])
+ matrix(
+ [['2.0']])
+
+ ..
+ COMMENT: TODO: the above "doctest:+SKIP" may be removed as soon as we
+ have dropped support for Python 3.5 and below.
+
+ You can raise powers of square matrices::
+
+ >>> A**2
+ matrix(
+ [['7.0', '10.0'],
+ ['15.0', '22.0']])
+
+ Negative powers will calculate the inverse::
+
+ >>> A**-1
+ matrix(
+ [['-2.0', '1.0'],
+ ['1.5', '-0.5']])
+ >>> A * A**-1
+ matrix(
+ [['1.0', '1.0842021724855e-19'],
+ ['-2.16840434497101e-19', '1.0']])
+
+
+
+ Matrix transposition is straightforward::
+
+ >>> A = ones(2, 3)
+ >>> A
+ matrix(
+ [['1.0', '1.0', '1.0'],
+ ['1.0', '1.0', '1.0']])
+ >>> A.T
+ matrix(
+ [['1.0', '1.0'],
+ ['1.0', '1.0'],
+ ['1.0', '1.0']])
+
+ Norms
+ .....
+
+ Sometimes you need to know how "large" a matrix or vector is. Due to their
+ multidimensional nature it's not possible to compare them, but there are
+ several functions to map a matrix or a vector to a positive real number, the
+ so called norms.
+
+ For vectors the p-norm is intended, usually the 1-, the 2- and the oo-norm are
+ used.
+
+ >>> x = matrix([-10, 2, 100])
+ >>> norm(x, 1)
+ mpf('112.0')
+ >>> norm(x, 2)
+ mpf('100.5186549850325')
+ >>> norm(x, inf)
+ mpf('100.0')
+
+ Please note that the 2-norm is the most used one, though it is more expensive
+ to calculate than the 1- or oo-norm.
+
+ It is possible to generalize some vector norms to matrix norm::
+
+ >>> A = matrix([[1, -1000], [100, 50]])
+ >>> mnorm(A, 1)
+ mpf('1050.0')
+ >>> mnorm(A, inf)
+ mpf('1001.0')
+ >>> mnorm(A, 'F')
+ mpf('1006.2310867787777')
+
+ The last norm (the "Frobenius-norm") is an approximation for the 2-norm, which
+ is hard to calculate and not available. The Frobenius-norm lacks some
+ mathematical properties you might expect from a norm.
+ """
+
+ def __init__(self, *args, **kwargs):
+ self.__data = {}
+ # LU decompostion cache, this is useful when solving the same system
+ # multiple times, when calculating the inverse and when calculating the
+ # determinant
+ self._LU = None
+ if "force_type" in kwargs:
+ warnings.warn("The force_type argument was removed, it did not work"
+ " properly anyway. If you want to force floating-point or"
+ " interval computations, use the respective methods from `fp`"
+ " or `mp` instead, e.g., `fp.matrix()` or `iv.matrix()`."
+ " If you want to truncate values to integer, use .apply(int) instead.")
+ if isinstance(args[0], (list, tuple)):
+ if isinstance(args[0][0], (list, tuple)):
+ # interpret nested list as matrix
+ A = args[0]
+ self.__rows = len(A)
+ self.__cols = len(A[0])
+ for i, row in enumerate(A):
+ for j, a in enumerate(row):
+ # note: this will call __setitem__ which will call self.ctx.convert() to convert the datatype.
+ self[i, j] = a
+ else:
+ # interpret list as row vector
+ v = args[0]
+ self.__rows = len(v)
+ self.__cols = 1
+ for i, e in enumerate(v):
+ self[i, 0] = e
+ elif isinstance(args[0], int):
+ # create empty matrix of given dimensions
+ if len(args) == 1:
+ self.__rows = self.__cols = args[0]
+ else:
+ if not isinstance(args[1], int):
+ raise TypeError("expected int")
+ self.__rows = args[0]
+ self.__cols = args[1]
+ elif isinstance(args[0], _matrix):
+ A = args[0]
+ self.__rows = A._matrix__rows
+ self.__cols = A._matrix__cols
+ for i in xrange(A.__rows):
+ for j in xrange(A.__cols):
+ self[i, j] = A[i, j]
+ elif hasattr(args[0], 'tolist'):
+ A = self.ctx.matrix(args[0].tolist())
+ self.__data = A._matrix__data
+ self.__rows = A._matrix__rows
+ self.__cols = A._matrix__cols
+ else:
+ raise TypeError('could not interpret given arguments')
+
+ def apply(self, f):
+ """
+ Return a copy of self with the function `f` applied elementwise.
+ """
+ new = self.ctx.matrix(self.__rows, self.__cols)
+ for i in xrange(self.__rows):
+ for j in xrange(self.__cols):
+ new[i,j] = f(self[i,j])
+ return new
+
+ def __nstr__(self, n=None, **kwargs):
+ # Build table of string representations of the elements
+ res = []
+ # Track per-column max lengths for pretty alignment
+ maxlen = [0] * self.cols
+ for i in range(self.rows):
+ res.append([])
+ for j in range(self.cols):
+ if n:
+ string = self.ctx.nstr(self[i,j], n, **kwargs)
+ else:
+ string = str(self[i,j])
+ res[-1].append(string)
+ maxlen[j] = max(len(string), maxlen[j])
+ # Patch strings together
+ for i, row in enumerate(res):
+ for j, elem in enumerate(row):
+ # Pad each element up to maxlen so the columns line up
+ row[j] = elem.rjust(maxlen[j])
+ res[i] = "[" + colsep.join(row) + "]"
+ return rowsep.join(res)
+
+ def __str__(self):
+ return self.__nstr__()
+
+ def _toliststr(self, avoid_type=False):
+ """
+ Create a list string from a matrix.
+
+ If avoid_type: avoid multiple 'mpf's.
+ """
+ # XXX: should be something like self.ctx._types
+ typ = self.ctx.mpf
+ s = '['
+ for i in xrange(self.__rows):
+ s += '['
+ for j in xrange(self.__cols):
+ if not avoid_type or not isinstance(self[i,j], typ):
+ a = repr(self[i,j])
+ else:
+ a = "'" + str(self[i,j]) + "'"
+ s += a + ', '
+ s = s[:-2]
+ s += '],\n '
+ s = s[:-3]
+ s += ']'
+ return s
+
+ def tolist(self):
+ """
+ Convert the matrix to a nested list.
+ """
+ return [[self[i,j] for j in range(self.__cols)] for i in range(self.__rows)]
+
+ def __repr__(self):
+ if self.ctx.pretty:
+ return self.__str__()
+ s = 'matrix(\n'
+ s += self._toliststr(avoid_type=True) + ')'
+ return s
+
+ def __get_element(self, key):
+ '''
+ Fast extraction of the i,j element from the matrix
+ This function is for private use only because is unsafe:
+ 1. Does not check on the value of key it expects key to be a integer tuple (i,j)
+ 2. Does not check bounds
+ '''
+ if key in self.__data:
+ return self.__data[key]
+ else:
+ return self.ctx.zero
+
+ def __set_element(self, key, value):
+ '''
+ Fast assignment of the i,j element in the matrix
+ This function is unsafe:
+ 1. Does not check on the value of key it expects key to be a integer tuple (i,j)
+ 2. Does not check bounds
+ 3. Does not check the value type
+ 4. Does not reset the LU cache
+ '''
+ if value: # only store non-zeros
+ self.__data[key] = value
+ elif key in self.__data:
+ del self.__data[key]
+
+
+ def __getitem__(self, key):
+ '''
+ Getitem function for mp matrix class with slice index enabled
+ it allows the following assingments
+ scalar to a slice of the matrix
+ B = A[:,2:6]
+ '''
+ # Convert vector to matrix indexing
+ if isinstance(key, int) or isinstance(key,slice):
+ # only sufficent for vectors
+ if self.__rows == 1:
+ key = (0, key)
+ elif self.__cols == 1:
+ key = (key, 0)
+ else:
+ raise IndexError('insufficient indices for matrix')
+
+ if isinstance(key[0],slice) or isinstance(key[1],slice):
+
+ #Rows
+ if isinstance(key[0],slice):
+ #Check bounds
+ if (key[0].start is None or key[0].start >= 0) and \
+ (key[0].stop is None or key[0].stop <= self.__rows+1):
+ # Generate indices
+ rows = xrange(*key[0].indices(self.__rows))
+ else:
+ raise IndexError('Row index out of bounds')
+ else:
+ # Single row
+ rows = [key[0]]
+
+ # Columns
+ if isinstance(key[1],slice):
+ # Check bounds
+ if (key[1].start is None or key[1].start >= 0) and \
+ (key[1].stop is None or key[1].stop <= self.__cols+1):
+ # Generate indices
+ columns = xrange(*key[1].indices(self.__cols))
+ else:
+ raise IndexError('Column index out of bounds')
+
+ else:
+ # Single column
+ columns = [key[1]]
+
+ # Create matrix slice
+ m = self.ctx.matrix(len(rows),len(columns))
+
+ # Assign elements to the output matrix
+ for i,x in enumerate(rows):
+ for j,y in enumerate(columns):
+ m.__set_element((i,j),self.__get_element((x,y)))
+
+ return m
+
+ else:
+ # single element extraction
+ if key[0] >= self.__rows or key[1] >= self.__cols:
+ raise IndexError('matrix index out of range')
+ if key in self.__data:
+ return self.__data[key]
+ else:
+ return self.ctx.zero
+
+ def __setitem__(self, key, value):
+ # setitem function for mp matrix class with slice index enabled
+ # it allows the following assingments
+ # scalar to a slice of the matrix
+ # A[:,2:6] = 2.5
+ # submatrix to matrix (the value matrix should be the same size as the slice size)
+ # A[3,:] = B where A is n x m and B is n x 1
+ # Convert vector to matrix indexing
+ if isinstance(key, int) or isinstance(key,slice):
+ # only sufficent for vectors
+ if self.__rows == 1:
+ key = (0, key)
+ elif self.__cols == 1:
+ key = (key, 0)
+ else:
+ raise IndexError('insufficient indices for matrix')
+ # Slice indexing
+ if isinstance(key[0],slice) or isinstance(key[1],slice):
+ # Rows
+ if isinstance(key[0],slice):
+ # Check bounds
+ if (key[0].start is None or key[0].start >= 0) and \
+ (key[0].stop is None or key[0].stop <= self.__rows+1):
+ # generate row indices
+ rows = xrange(*key[0].indices(self.__rows))
+ else:
+ raise IndexError('Row index out of bounds')
+ else:
+ # Single row
+ rows = [key[0]]
+ # Columns
+ if isinstance(key[1],slice):
+ # Check bounds
+ if (key[1].start is None or key[1].start >= 0) and \
+ (key[1].stop is None or key[1].stop <= self.__cols+1):
+ # Generate column indices
+ columns = xrange(*key[1].indices(self.__cols))
+ else:
+ raise IndexError('Column index out of bounds')
+ else:
+ # Single column
+ columns = [key[1]]
+ # Assign slice with a scalar
+ if isinstance(value,self.ctx.matrix):
+ # Assign elements to matrix if input and output dimensions match
+ if len(rows) == value.rows and len(columns) == value.cols:
+ for i,x in enumerate(rows):
+ for j,y in enumerate(columns):
+ self.__set_element((x,y), value.__get_element((i,j)))
+ else:
+ raise ValueError('Dimensions do not match')
+ else:
+ # Assign slice with scalars
+ value = self.ctx.convert(value)
+ for i in rows:
+ for j in columns:
+ self.__set_element((i,j), value)
+ else:
+ # Single element assingment
+ # Check bounds
+ if key[0] >= self.__rows or key[1] >= self.__cols:
+ raise IndexError('matrix index out of range')
+ # Convert and store value
+ value = self.ctx.convert(value)
+ if value: # only store non-zeros
+ self.__data[key] = value
+ elif key in self.__data:
+ del self.__data[key]
+
+ if self._LU:
+ self._LU = None
+ return
+
+ def __iter__(self):
+ for i in xrange(self.__rows):
+ for j in xrange(self.__cols):
+ yield self[i,j]
+
+ def __mul__(self, other):
+ if isinstance(other, self.ctx.matrix):
+ # dot multiplication
+ if self.__cols != other.__rows:
+ raise ValueError('dimensions not compatible for multiplication')
+ new = self.ctx.matrix(self.__rows, other.__cols)
+ self_zero = self.ctx.zero
+ self_get = self.__data.get
+ other_zero = other.ctx.zero
+ other_get = other.__data.get
+ for i in xrange(self.__rows):
+ for j in xrange(other.__cols):
+ new[i, j] = self.ctx.fdot((self_get((i,k), self_zero), other_get((k,j), other_zero))
+ for k in xrange(other.__rows))
+ return new
+ else:
+ # try scalar multiplication
+ new = self.ctx.matrix(self.__rows, self.__cols)
+ for i in xrange(self.__rows):
+ for j in xrange(self.__cols):
+ new[i, j] = other * self[i, j]
+ return new
+
+ def __matmul__(self, other):
+ return self.__mul__(other)
+
+ def __rmul__(self, other):
+ # assume other is scalar and thus commutative
+ if isinstance(other, self.ctx.matrix):
+ raise TypeError("other should not be type of ctx.matrix")
+ return self.__mul__(other)
+
+ def __pow__(self, other):
+ # avoid cyclic import problems
+ #from linalg import inverse
+ if not isinstance(other, int):
+ raise ValueError('only integer exponents are supported')
+ if not self.__rows == self.__cols:
+ raise ValueError('only powers of square matrices are defined')
+ n = other
+ if n == 0:
+ return self.ctx.eye(self.__rows)
+ if n < 0:
+ n = -n
+ neg = True
+ else:
+ neg = False
+ i = n
+ y = 1
+ z = self.copy()
+ while i != 0:
+ if i % 2 == 1:
+ y = y * z
+ z = z*z
+ i = i // 2
+ if neg:
+ y = self.ctx.inverse(y)
+ return y
+
+ def __div__(self, other):
+ # assume other is scalar and do element-wise divison
+ assert not isinstance(other, self.ctx.matrix)
+ new = self.ctx.matrix(self.__rows, self.__cols)
+ for i in xrange(self.__rows):
+ for j in xrange(self.__cols):
+ new[i,j] = self[i,j] / other
+ return new
+
+ __truediv__ = __div__
+
+ def __add__(self, other):
+ if isinstance(other, self.ctx.matrix):
+ if not (self.__rows == other.__rows and self.__cols == other.__cols):
+ raise ValueError('incompatible dimensions for addition')
+ new = self.ctx.matrix(self.__rows, self.__cols)
+ for i in xrange(self.__rows):
+ for j in xrange(self.__cols):
+ new[i,j] = self[i,j] + other[i,j]
+ return new
+ else:
+ # assume other is scalar and add element-wise
+ new = self.ctx.matrix(self.__rows, self.__cols)
+ for i in xrange(self.__rows):
+ for j in xrange(self.__cols):
+ new[i,j] += self[i,j] + other
+ return new
+
+ def __radd__(self, other):
+ return self.__add__(other)
+
+ def __sub__(self, other):
+ if isinstance(other, self.ctx.matrix) and not (self.__rows == other.__rows
+ and self.__cols == other.__cols):
+ raise ValueError('incompatible dimensions for subtraction')
+ return self.__add__(other * (-1))
+
+ def __pos__(self):
+ """
+ +M returns a copy of M, rounded to current working precision.
+ """
+ return (+1) * self
+
+ def __neg__(self):
+ return (-1) * self
+
+ def __rsub__(self, other):
+ return -self + other
+
+ def __eq__(self, other):
+ return self.__rows == other.__rows and self.__cols == other.__cols \
+ and self.__data == other.__data
+
+ def __len__(self):
+ if self.rows == 1:
+ return self.cols
+ elif self.cols == 1:
+ return self.rows
+ else:
+ return self.rows # do it like numpy
+
+ def __getrows(self):
+ return self.__rows
+
+ def __setrows(self, value):
+ for key in self.__data.copy():
+ if key[0] >= value:
+ del self.__data[key]
+ self.__rows = value
+
+ rows = property(__getrows, __setrows, doc='number of rows')
+
+ def __getcols(self):
+ return self.__cols
+
+ def __setcols(self, value):
+ for key in self.__data.copy():
+ if key[1] >= value:
+ del self.__data[key]
+ self.__cols = value
+
+ cols = property(__getcols, __setcols, doc='number of columns')
+
+ def transpose(self):
+ new = self.ctx.matrix(self.__cols, self.__rows)
+ for i in xrange(self.__rows):
+ for j in xrange(self.__cols):
+ new[j,i] = self[i,j]
+ return new
+
+ T = property(transpose)
+
+ def conjugate(self):
+ return self.apply(self.ctx.conj)
+
+ def transpose_conj(self):
+ return self.conjugate().transpose()
+
+ H = property(transpose_conj)
+
+ def copy(self):
+ new = self.ctx.matrix(self.__rows, self.__cols)
+ new.__data = self.__data.copy()
+ return new
+
+ __copy__ = copy
+
+ def column(self, n):
+ m = self.ctx.matrix(self.rows, 1)
+ for i in range(self.rows):
+ m[i] = self[i,n]
+ return m
+
+class MatrixMethods(object):
+
+ def __init__(ctx):
+ # XXX: subclass
+ ctx.matrix = type('matrix', (_matrix,), {})
+ ctx.matrix.ctx = ctx
+ ctx.matrix.convert = ctx.convert
+
+ def eye(ctx, n, **kwargs):
+ """
+ Create square identity matrix n x n.
+ """
+ A = ctx.matrix(n, **kwargs)
+ for i in xrange(n):
+ A[i,i] = 1
+ return A
+
+ def diag(ctx, diagonal, **kwargs):
+ """
+ Create square diagonal matrix using given list.
+
+ Example:
+ >>> from mpmath import diag, mp
+ >>> mp.pretty = False
+ >>> diag([1, 2, 3])
+ matrix(
+ [['1.0', '0.0', '0.0'],
+ ['0.0', '2.0', '0.0'],
+ ['0.0', '0.0', '3.0']])
+ """
+ A = ctx.matrix(len(diagonal), **kwargs)
+ for i in xrange(len(diagonal)):
+ A[i,i] = diagonal[i]
+ return A
+
+ def zeros(ctx, *args, **kwargs):
+ """
+ Create matrix m x n filled with zeros.
+ One given dimension will create square matrix n x n.
+
+ Example:
+ >>> from mpmath import zeros, mp
+ >>> mp.pretty = False
+ >>> zeros(2)
+ matrix(
+ [['0.0', '0.0'],
+ ['0.0', '0.0']])
+ """
+ if len(args) == 1:
+ m = n = args[0]
+ elif len(args) == 2:
+ m = args[0]
+ n = args[1]
+ else:
+ raise TypeError('zeros expected at most 2 arguments, got %i' % len(args))
+ A = ctx.matrix(m, n, **kwargs)
+ for i in xrange(m):
+ for j in xrange(n):
+ A[i,j] = 0
+ return A
+
+ def ones(ctx, *args, **kwargs):
+ """
+ Create matrix m x n filled with ones.
+ One given dimension will create square matrix n x n.
+
+ Example:
+ >>> from mpmath import ones, mp
+ >>> mp.pretty = False
+ >>> ones(2)
+ matrix(
+ [['1.0', '1.0'],
+ ['1.0', '1.0']])
+ """
+ if len(args) == 1:
+ m = n = args[0]
+ elif len(args) == 2:
+ m = args[0]
+ n = args[1]
+ else:
+ raise TypeError('ones expected at most 2 arguments, got %i' % len(args))
+ A = ctx.matrix(m, n, **kwargs)
+ for i in xrange(m):
+ for j in xrange(n):
+ A[i,j] = 1
+ return A
+
+ def hilbert(ctx, m, n=None):
+ """
+ Create (pseudo) hilbert matrix m x n.
+ One given dimension will create hilbert matrix n x n.
+
+ The matrix is very ill-conditioned and symmetric, positive definite if
+ square.
+ """
+ if n is None:
+ n = m
+ A = ctx.matrix(m, n)
+ for i in xrange(m):
+ for j in xrange(n):
+ A[i,j] = ctx.one / (i + j + 1)
+ return A
+
+ def randmatrix(ctx, m, n=None, min=0, max=1, **kwargs):
+ """
+ Create a random m x n matrix.
+
+ All values are >= min and >> from mpmath import randmatrix
+ >>> randmatrix(2) # doctest:+SKIP
+ matrix(
+ [['0.53491598236191806', '0.57195669543302752'],
+ ['0.85589992269513615', '0.82444367501382143']])
+ """
+ if not n:
+ n = m
+ A = ctx.matrix(m, n, **kwargs)
+ for i in xrange(m):
+ for j in xrange(n):
+ A[i,j] = ctx.rand() * (max - min) + min
+ return A
+
+ def swap_row(ctx, A, i, j):
+ """
+ Swap row i with row j.
+ """
+ if i == j:
+ return
+ if isinstance(A, ctx.matrix):
+ for k in xrange(A.cols):
+ A[i,k], A[j,k] = A[j,k], A[i,k]
+ elif isinstance(A, list):
+ A[i], A[j] = A[j], A[i]
+ else:
+ raise TypeError('could not interpret type')
+
+ def extend(ctx, A, b):
+ """
+ Extend matrix A with column b and return result.
+ """
+ if not isinstance(A, ctx.matrix):
+ raise TypeError("A should be a type of ctx.matrix")
+ if A.rows != len(b):
+ raise ValueError("Value should be equal to len(b)")
+ A = A.copy()
+ A.cols += 1
+ for i in xrange(A.rows):
+ A[i, A.cols-1] = b[i]
+ return A
+
+ def norm(ctx, x, p=2):
+ r"""
+ Gives the entrywise `p`-norm of an iterable *x*, i.e. the vector norm
+ `\left(\sum_k |x_k|^p\right)^{1/p}`, for any given `1 \le p \le \infty`.
+
+ Special cases:
+
+ If *x* is not iterable, this just returns ``absmax(x)``.
+
+ ``p=1`` gives the sum of absolute values.
+
+ ``p=2`` is the standard Euclidean vector norm.
+
+ ``p=inf`` gives the magnitude of the largest element.
+
+ For *x* a matrix, ``p=2`` is the Frobenius norm.
+ For operator matrix norms, use :func:`~mpmath.mnorm` instead.
+
+ You can use the string 'inf' as well as float('inf') or mpf('inf')
+ to specify the infinity norm.
+
+ **Examples**
+
+ >>> from mpmath import *
+ >>> mp.dps = 15; mp.pretty = False
+ >>> x = matrix([-10, 2, 100])
+ >>> norm(x, 1)
+ mpf('112.0')
+ >>> norm(x, 2)
+ mpf('100.5186549850325')
+ >>> norm(x, inf)
+ mpf('100.0')
+
+ """
+ try:
+ iter(x)
+ except TypeError:
+ return ctx.absmax(x)
+ if type(p) is not int:
+ p = ctx.convert(p)
+ if p == ctx.inf:
+ return max(ctx.absmax(i) for i in x)
+ elif p == 1:
+ return ctx.fsum(x, absolute=1)
+ elif p == 2:
+ return ctx.sqrt(ctx.fsum(x, absolute=1, squared=1))
+ elif p > 1:
+ return ctx.nthroot(ctx.fsum(abs(i)**p for i in x), p)
+ else:
+ raise ValueError('p has to be >= 1')
+
+ def mnorm(ctx, A, p=1):
+ r"""
+ Gives the matrix (operator) `p`-norm of A. Currently ``p=1`` and ``p=inf``
+ are supported:
+
+ ``p=1`` gives the 1-norm (maximal column sum)
+
+ ``p=inf`` gives the `\infty`-norm (maximal row sum).
+ You can use the string 'inf' as well as float('inf') or mpf('inf')
+
+ ``p=2`` (not implemented) for a square matrix is the usual spectral
+ matrix norm, i.e. the largest singular value.
+
+ ``p='f'`` (or 'F', 'fro', 'Frobenius, 'frobenius') gives the
+ Frobenius norm, which is the elementwise 2-norm. The Frobenius norm is an
+ approximation of the spectral norm and satisfies
+
+ .. math ::
+
+ \frac{1}{\sqrt{\mathrm{rank}(A)}} \|A\|_F \le \|A\|_2 \le \|A\|_F
+
+ The Frobenius norm lacks some mathematical properties that might
+ be expected of a norm.
+
+ For general elementwise `p`-norms, use :func:`~mpmath.norm` instead.
+
+ **Examples**
+
+ >>> from mpmath import *
+ >>> mp.dps = 15; mp.pretty = False
+ >>> A = matrix([[1, -1000], [100, 50]])
+ >>> mnorm(A, 1)
+ mpf('1050.0')
+ >>> mnorm(A, inf)
+ mpf('1001.0')
+ >>> mnorm(A, 'F')
+ mpf('1006.2310867787777')
+
+ """
+ A = ctx.matrix(A)
+ if type(p) is not int:
+ if type(p) is str and 'frobenius'.startswith(p.lower()):
+ return ctx.norm(A, 2)
+ p = ctx.convert(p)
+ m, n = A.rows, A.cols
+ if p == 1:
+ return max(ctx.fsum((A[i,j] for i in xrange(m)), absolute=1) for j in xrange(n))
+ elif p == ctx.inf:
+ return max(ctx.fsum((A[i,j] for j in xrange(n)), absolute=1) for i in xrange(m))
+ else:
+ raise NotImplementedError("matrix p-norm for arbitrary p")
+
+if __name__ == '__main__':
+ import doctest
+ doctest.testmod()
diff --git a/lib/python3.10/site-packages/mpmath/tests/__init__.py b/lib/python3.10/site-packages/mpmath/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/__init__.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..77ba1fdb513963c92a7a49948cd754bc523669f9
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/__init__.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/extratest_gamma.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/extratest_gamma.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8923a47b9b875d65f275c5b7058ce66ddb27d514
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/extratest_gamma.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/extratest_zeta.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/extratest_zeta.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5fa5953c3821eaacf7b0d25e85df97d06526e994
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/extratest_zeta.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/runtests.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/runtests.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..551fedca5c1583545630677d15372f8944dcfc3e
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/runtests.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_basic_ops.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_basic_ops.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..78213513b751252df59bded322d6b02f73d18ae7
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_basic_ops.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_bitwise.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_bitwise.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..78df1cf82be81e130b368a707eab3c52137b20fe
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_bitwise.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_calculus.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_calculus.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..73a5a421a32e7c95fac0be2816d8a8cdc0ddf436
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_calculus.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_compatibility.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_compatibility.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..07025a0406896eef91b669d23b502d04cf51d98f
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_compatibility.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_convert.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_convert.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1f85ff33c3a6b6ddc66f0fa7ed32e107da6a627e
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_convert.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_diff.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_diff.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..595f10f32f5cdb8550ced60457c9412dcf7d5d30
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_diff.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_division.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_division.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a900bd2f45a14f09b48a1d2828dcb4bde34ccbb5
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_division.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_eigen.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_eigen.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e00b7e8750799694f6048d34f22d8f2f16bb9972
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_eigen.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_eigen_symmetric.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_eigen_symmetric.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..06ed54fca6d998a666d527d2702188247757da68
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_eigen_symmetric.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_elliptic.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_elliptic.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..326a8d160137d2428723e777f499f9611f86c164
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_elliptic.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_fp.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_fp.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..985da435c4f5915ae9dfba4392ef916b7b559a87
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_fp.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_functions.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_functions.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..cbd7a0a5d7eb3e896c272757b9065185d9dd1031
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_functions.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_functions2.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_functions2.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..99c5400c186f927ff158839d65428deec9da4259
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_functions2.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_gammazeta.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_gammazeta.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..48c7940fb2664f870678b51c6c5303b73a5ebfa2
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_gammazeta.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_hp.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_hp.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ac793a562882868263396c4519b166db4b6c583a
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_hp.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_identify.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_identify.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3178c10ddd68fa96784d849a9cf094da81ca8105
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_identify.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_interval.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_interval.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8fb7e51847fd7335f177dea19b13ddb4407025ee
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_interval.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_levin.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_levin.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..cf27fde6b7a8130fd342cbb6a3a5b418f2fab891
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_levin.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_linalg.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_linalg.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..85b69c88c83a82f64fedb8dc2878fd349976d414
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_linalg.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_matrices.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_matrices.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..92747c7c2e54ff32301434b3facdf2ef0256cb64
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_matrices.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_mpmath.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_mpmath.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f1a19f3707a95c14a43c1e3bde338af3f7addfb6
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_mpmath.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_ode.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_ode.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a6a7b10e9c19a2eb11f952389ff6cfb3b21acbe1
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_ode.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_pickle.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_pickle.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2b28c1887b3348a6b0c9131318c6976b2567d352
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_pickle.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_power.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_power.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c348c3008a56cad31f1d3ae36536f6a524e05e11
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_power.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_quad.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_quad.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..90019ba580293cb120f9b6862946f52a182701fb
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_quad.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_rootfinding.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_rootfinding.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0c6233b7932678b4e9097c3e93f31cd884ef966d
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_rootfinding.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_special.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_special.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..217a28758b2b47d209a38007048900c9baa852d5
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_special.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_str.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_str.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..57fc366448117b8cef6184f1c372706e37ceded9
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_str.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_summation.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_summation.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..065bbde41fcead36f465c82502d037d6499516ac
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_summation.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_trig.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_trig.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..87bd15cba45f26c879688b28b93e69b5f873b1ee
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_trig.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_visualization.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_visualization.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f0c931fbde157b242f961450439fd89d9365cdc3
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/test_visualization.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/__pycache__/torture.cpython-310.pyc b/lib/python3.10/site-packages/mpmath/tests/__pycache__/torture.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5970355e75aaa565a299d3c8576b497ba4a4d3f6
Binary files /dev/null and b/lib/python3.10/site-packages/mpmath/tests/__pycache__/torture.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/mpmath/tests/extratest_gamma.py b/lib/python3.10/site-packages/mpmath/tests/extratest_gamma.py
new file mode 100644
index 0000000000000000000000000000000000000000..5a27b61b19aba0abf6bdb8adc16fc1ec7689b67a
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/extratest_gamma.py
@@ -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)
diff --git a/lib/python3.10/site-packages/mpmath/tests/extratest_zeta.py b/lib/python3.10/site-packages/mpmath/tests/extratest_zeta.py
new file mode 100644
index 0000000000000000000000000000000000000000..582b3d9cbd956b9cdf94309e0e718371fe716101
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/extratest_zeta.py
@@ -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()
diff --git a/lib/python3.10/site-packages/mpmath/tests/runtests.py b/lib/python3.10/site-packages/mpmath/tests/runtests.py
new file mode 100644
index 0000000000000000000000000000000000000000..70fde272fdc0e05e3d8951edddca380bd36139ab
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/runtests.py
@@ -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)
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_basic_ops.py b/lib/python3.10/site-packages/mpmath/tests/test_basic_ops.py
new file mode 100644
index 0000000000000000000000000000000000000000..f577c7fa9f9734876b6767f6cc21144df305d82f
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_basic_ops.py
@@ -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_
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_bitwise.py b/lib/python3.10/site-packages/mpmath/tests/test_bitwise.py
new file mode 100644
index 0000000000000000000000000000000000000000..4f61b69fc8819cf275abaedd98847c58c3b5924a
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_bitwise.py
@@ -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
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_calculus.py b/lib/python3.10/site-packages/mpmath/tests/test_calculus.py
new file mode 100644
index 0000000000000000000000000000000000000000..f0a59773d672f0db20bb5072773472a5a3cc1d1f
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_calculus.py
@@ -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)
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_compatibility.py b/lib/python3.10/site-packages/mpmath/tests/test_compatibility.py
new file mode 100644
index 0000000000000000000000000000000000000000..f26d6044b521306b6d1eaeadc5c7839be226dc54
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_compatibility.py
@@ -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)
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_convert.py b/lib/python3.10/site-packages/mpmath/tests/test_convert.py
new file mode 100644
index 0000000000000000000000000000000000000000..cb1db5b55c89e980e08fc3fa43cc9715ad68cac9
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_convert.py
@@ -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
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_diff.py b/lib/python3.10/site-packages/mpmath/tests/test_diff.py
new file mode 100644
index 0000000000000000000000000000000000000000..f5711609da38862eb4fd62c88d35f1704c9425a4
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_diff.py
@@ -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)
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_division.py b/lib/python3.10/site-packages/mpmath/tests/test_division.py
new file mode 100644
index 0000000000000000000000000000000000000000..c704cadeb953793ac0a887aa09c4278cf68a2824
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_division.py
@@ -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< 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)
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_eigen_symmetric.py b/lib/python3.10/site-packages/mpmath/tests/test_eigen_symmetric.py
new file mode 100644
index 0000000000000000000000000000000000000000..aab3d8ea3142aada6e14ad6d3ea25a7e8293554d
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_eigen_symmetric.py
@@ -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) )
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_elliptic.py b/lib/python3.10/site-packages/mpmath/tests/test_elliptic.py
new file mode 100644
index 0000000000000000000000000000000000000000..4dddc2df34b8d2fa7f2028b3501e5b7f140d8912
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_elliptic.py
@@ -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))
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_fp.py b/lib/python3.10/site-packages/mpmath/tests/test_fp.py
new file mode 100644
index 0000000000000000000000000000000000000000..99f3759c3071c4d55e0481472f3d16c1f5df1fef
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_fp.py
@@ -0,0 +1,1671 @@
+"""
+Easy-to-use test-generating code:
+
+cases = '''
+exp 2.25
+log 2.25
+'''
+
+from mpmath import *
+mp.dps = 20
+for test in cases.splitlines():
+ if not test:
+ continue
+ words = test.split()
+ fname = words[0]
+ args = words[1:]
+ argstr = ", ".join(args)
+ testline = "%s(%s)" % (fname, argstr)
+ ans = str(eval(testline))
+ print " assert ae(fp.%s, %s)" % (testline, ans)
+
+"""
+
+from mpmath import fp
+
+def ae(x, y, tol=1e-12):
+ if x == y:
+ return True
+ return abs(x-y) <= tol*abs(y)
+
+def test_conj():
+ assert fp.conj(4) == 4
+ assert fp.conj(3+4j) == 3-4j
+ assert fp.fdot([1,2],[3,2+1j], conjugate=True) == 7-2j
+
+def test_fp_number_parts():
+ assert ae(fp.arg(3), 0.0)
+ assert ae(fp.arg(-3), 3.1415926535897932385)
+ assert ae(fp.arg(3j), 1.5707963267948966192)
+ assert ae(fp.arg(-3j), -1.5707963267948966192)
+ assert ae(fp.arg(2+3j), 0.98279372324732906799)
+ assert ae(fp.arg(-1-1j), -2.3561944901923449288)
+ assert ae(fp.re(2.5), 2.5)
+ assert ae(fp.re(2.5+3j), 2.5)
+ assert ae(fp.im(2.5), 0.0)
+ assert ae(fp.im(2.5+3j), 3.0)
+ assert ae(fp.floor(2.5), 2.0)
+ assert ae(fp.floor(2), 2.0)
+ assert ae(fp.floor(2.0+0j), (2.0 + 0.0j))
+ assert ae(fp.floor(-1.5-0.5j), (-2.0 - 1.0j))
+ assert ae(fp.ceil(2.5), 3.0)
+ assert ae(fp.ceil(2), 2.0)
+ assert ae(fp.ceil(2.0+0j), (2.0 + 0.0j))
+ assert ae(fp.ceil(-1.5-0.5j), (-1.0 + 0.0j))
+
+def test_fp_cospi_sinpi():
+ assert ae(fp.sinpi(0), 0.0)
+ assert ae(fp.sinpi(0.25), 0.7071067811865475244)
+ assert ae(fp.sinpi(0.5), 1.0)
+ assert ae(fp.sinpi(0.75), 0.7071067811865475244)
+ assert ae(fp.sinpi(1), 0.0)
+ assert ae(fp.sinpi(1.25), -0.7071067811865475244)
+ assert ae(fp.sinpi(1.5), -1.0)
+ assert ae(fp.sinpi(1.75), -0.7071067811865475244)
+ assert ae(fp.sinpi(2), 0.0)
+ assert ae(fp.sinpi(2.25), 0.7071067811865475244)
+ assert ae(fp.sinpi(0+3j), (0.0 + 6195.8238636085899556j))
+ assert ae(fp.sinpi(0.25+3j), (4381.1091260582448033 + 4381.1090689950686908j))
+ assert ae(fp.sinpi(0.5+3j), (6195.8239443081075259 + 0.0j))
+ assert ae(fp.sinpi(0.75+3j), (4381.1091260582448033 - 4381.1090689950686908j))
+ assert ae(fp.sinpi(1+3j), (0.0 - 6195.8238636085899556j))
+ assert ae(fp.sinpi(1.25+3j), (-4381.1091260582448033 - 4381.1090689950686908j))
+ assert ae(fp.sinpi(1.5+3j), (-6195.8239443081075259 + 0.0j))
+ assert ae(fp.sinpi(1.75+3j), (-4381.1091260582448033 + 4381.1090689950686908j))
+ assert ae(fp.sinpi(2+3j), (0.0 + 6195.8238636085899556j))
+ assert ae(fp.sinpi(2.25+3j), (4381.1091260582448033 + 4381.1090689950686908j))
+ assert ae(fp.sinpi(-0.75), -0.7071067811865475244)
+ assert ae(fp.sinpi(-1e-10), -3.1415926535897933529e-10)
+ assert ae(fp.sinpi(1e-10), 3.1415926535897933529e-10)
+ assert ae(fp.sinpi(1e-10+1e-10j), (3.141592653589793353e-10 + 3.1415926535897933528e-10j))
+ assert ae(fp.sinpi(1e-10-1e-10j), (3.141592653589793353e-10 - 3.1415926535897933528e-10j))
+ assert ae(fp.sinpi(-1e-10+1e-10j), (-3.141592653589793353e-10 + 3.1415926535897933528e-10j))
+ assert ae(fp.sinpi(-1e-10-1e-10j), (-3.141592653589793353e-10 - 3.1415926535897933528e-10j))
+ assert ae(fp.cospi(0), 1.0)
+ assert ae(fp.cospi(0.25), 0.7071067811865475244)
+ assert ae(fp.cospi(0.5), 0.0)
+ assert ae(fp.cospi(0.75), -0.7071067811865475244)
+ assert ae(fp.cospi(1), -1.0)
+ assert ae(fp.cospi(1.25), -0.7071067811865475244)
+ assert ae(fp.cospi(1.5), 0.0)
+ assert ae(fp.cospi(1.75), 0.7071067811865475244)
+ assert ae(fp.cospi(2), 1.0)
+ assert ae(fp.cospi(2.25), 0.7071067811865475244)
+ assert ae(fp.cospi(0+3j), (6195.8239443081075259 + 0.0j))
+ assert ae(fp.cospi(0.25+3j), (4381.1091260582448033 - 4381.1090689950686908j))
+ assert ae(fp.cospi(0.5+3j), (0.0 - 6195.8238636085899556j))
+ assert ae(fp.cospi(0.75+3j), (-4381.1091260582448033 - 4381.1090689950686908j))
+ assert ae(fp.cospi(1+3j), (-6195.8239443081075259 + 0.0j))
+ assert ae(fp.cospi(1.25+3j), (-4381.1091260582448033 + 4381.1090689950686908j))
+ assert ae(fp.cospi(1.5+3j), (0.0 + 6195.8238636085899556j))
+ assert ae(fp.cospi(1.75+3j), (4381.1091260582448033 + 4381.1090689950686908j))
+ assert ae(fp.cospi(2+3j), (6195.8239443081075259 + 0.0j))
+ assert ae(fp.cospi(2.25+3j), (4381.1091260582448033 - 4381.1090689950686908j))
+ assert ae(fp.cospi(-0.75), -0.7071067811865475244)
+ assert ae(fp.sinpi(-0.7), -0.80901699437494750611)
+ assert ae(fp.cospi(-0.7), -0.5877852522924730163)
+ assert ae(fp.cospi(-3+2j), (-267.74676148374822225 + 0.0j))
+ assert ae(fp.sinpi(-3+2j), (0.0 - 267.74489404101651426j))
+ assert ae(fp.sinpi(-0.7+2j), (-216.6116802292079471 - 157.37650009392034693j))
+ assert ae(fp.cospi(-0.7+2j), (-157.37759774921754565 + 216.61016943630197336j))
+
+def test_fp_expj():
+ assert ae(fp.expj(0), (1.0 + 0.0j))
+ assert ae(fp.expj(1), (0.5403023058681397174 + 0.84147098480789650665j))
+ assert ae(fp.expj(2), (-0.416146836547142387 + 0.9092974268256816954j))
+ assert ae(fp.expj(0.75), (0.73168886887382088631 + 0.68163876002333416673j))
+ assert ae(fp.expj(2+3j), (-0.020718731002242879378 + 0.045271253156092975488j))
+ assert ae(fp.expjpi(0), (1.0 + 0.0j))
+ assert ae(fp.expjpi(1), (-1.0 + 0.0j))
+ assert ae(fp.expjpi(2), (1.0 + 0.0j))
+ assert ae(fp.expjpi(0.75), (-0.7071067811865475244 + 0.7071067811865475244j))
+ assert ae(fp.expjpi(2+3j), (0.000080699517570304599239 + 0.0j))
+
+def test_fp_bernoulli():
+ assert ae(fp.bernoulli(0), 1.0)
+ assert ae(fp.bernoulli(1), -0.5)
+ assert ae(fp.bernoulli(2), 0.16666666666666666667)
+ assert ae(fp.bernoulli(10), 0.075757575757575757576)
+ assert ae(fp.bernoulli(11), 0.0)
+
+def test_fp_gamma():
+ assert ae(fp.gamma(1), 1.0)
+ assert ae(fp.gamma(1.5), 0.88622692545275801365)
+ assert ae(fp.gamma(10), 362880.0)
+ assert ae(fp.gamma(-0.5), -3.5449077018110320546)
+ assert ae(fp.gamma(-7.1), 0.0016478244570263333622)
+ assert ae(fp.gamma(12.3), 83385367.899970000963)
+ assert ae(fp.gamma(2+0j), (1.0 + 0.0j))
+ assert ae(fp.gamma(-2.5+0j), (-0.94530872048294188123 + 0.0j))
+ assert ae(fp.gamma(3+4j), (0.0052255384713692141947 - 0.17254707929430018772j))
+ assert ae(fp.gamma(-3-4j), (0.00001460997305874775607 - 0.000020760733311509070396j))
+ assert ae(fp.fac(0), 1.0)
+ assert ae(fp.fac(1), 1.0)
+ assert ae(fp.fac(20), 2432902008176640000.0)
+ assert ae(fp.fac(-3.5), -0.94530872048294188123)
+ assert ae(fp.fac(2+3j), (-0.44011340763700171113 - 0.06363724312631702183j))
+ assert ae(fp.loggamma(1.0), 0.0)
+ assert ae(fp.loggamma(2.0), 0.0)
+ assert ae(fp.loggamma(3.0), 0.69314718055994530942)
+ assert ae(fp.loggamma(7.25), 7.0521854507385394449)
+ assert ae(fp.loggamma(1000.0), 5905.2204232091812118)
+ assert ae(fp.loggamma(1e50), 1.1412925464970229298e+52)
+ assert ae(fp.loggamma(1e25+1e25j), (5.6125802751733671621e+26 + 5.7696599078528568383e+26j))
+ assert ae(fp.loggamma(3+4j), (-1.7566267846037841105 + 4.7426644380346579282j))
+ assert ae(fp.loggamma(-0.5), (1.2655121234846453965 - 3.1415926535897932385j))
+ assert ae(fp.loggamma(-1.25), (1.3664317612369762346 - 6.2831853071795864769j))
+ assert ae(fp.loggamma(-2.75), (0.0044878975359557733115 - 9.4247779607693797154j))
+ assert ae(fp.loggamma(-3.5), (-1.3090066849930420464 - 12.566370614359172954j))
+ assert ae(fp.loggamma(-4.5), (-2.8130840817693161197 - 15.707963267948966192j))
+ assert ae(fp.loggamma(-2+3j), (-6.776523813485657093 - 4.568791367260286402j))
+ assert ae(fp.loggamma(-1000.3), (-5912.8440347785205041 - 3144.7342462433830317j))
+ assert ae(fp.loggamma(-100-100j), (-632.35117666833135562 - 158.37641469650352462j))
+ assert ae(fp.loggamma(1e-10), 23.025850929882735237)
+ assert ae(fp.loggamma(-1e-10), (23.02585092999817837 - 3.1415926535897932385j))
+ assert ae(fp.loggamma(1e-10j), (23.025850929940456804 - 1.5707963268526181857j))
+ assert ae(fp.loggamma(1e-10j-1e-10), (22.679277339718205716 - 2.3561944902500664954j))
+
+def test_fp_psi():
+ assert ae(fp.psi(0, 3.7), 1.1671535393615114409)
+ assert ae(fp.psi(0, 0.5), -1.9635100260214234794)
+ assert ae(fp.psi(0, 1), -0.57721566490153286061)
+ assert ae(fp.psi(0, -2.5), 1.1031566406452431872)
+ assert ae(fp.psi(0, 12.9), 2.5179671503279156347)
+ assert ae(fp.psi(0, 100), 4.6001618527380874002)
+ assert ae(fp.psi(0, 2500.3), 7.8239660143238547877)
+ assert ae(fp.psi(0, 1e40), 92.103403719761827391)
+ assert ae(fp.psi(0, 1e200), 460.51701859880913677)
+ assert ae(fp.psi(0, 3.7+0j), (1.1671535393615114409 + 0.0j))
+ assert ae(fp.psi(1, 3), 0.39493406684822643647)
+ assert ae(fp.psi(3, 2+3j), (-0.05383196209159972116 + 0.0076890935247364805218j))
+ assert ae(fp.psi(4, -0.5+1j), (1.2719531355492328195 - 18.211833410936276774j))
+ assert ae(fp.harmonic(0), 0.0)
+ assert ae(fp.harmonic(1), 1.0)
+ assert ae(fp.harmonic(2), 1.5)
+ assert ae(fp.harmonic(100), 5.1873775176396202608)
+ assert ae(fp.harmonic(-2.5), 1.2803723055467760478)
+ assert ae(fp.harmonic(2+3j), (1.9390425294578375875 + 0.87336044981834544043j))
+ assert ae(fp.harmonic(-5-4j), (2.3725754822349437733 - 2.4160904444801621j))
+
+def test_fp_zeta():
+ assert ae(fp.zeta(1e100), 1.0)
+ assert ae(fp.zeta(3), 1.2020569031595942854)
+ assert ae(fp.zeta(2+0j), (1.6449340668482264365 + 0.0j))
+ assert ae(fp.zeta(0.93), -13.713619351638164784)
+ assert ae(fp.zeta(1.74), 1.9796863545771774095)
+ assert ae(fp.zeta(0.0), -0.5)
+ assert ae(fp.zeta(-1.0), -0.083333333333333333333)
+ assert ae(fp.zeta(-2.0), 0.0)
+ assert ae(fp.zeta(-3.0), 0.0083333333333333333333)
+ assert ae(fp.zeta(-500.0), 0.0)
+ assert ae(fp.zeta(-7.4), 0.0036537321227995882447)
+ assert ae(fp.zeta(2.1), 1.5602165335033620158)
+ assert ae(fp.zeta(26.9), 1.0000000079854809935)
+ assert ae(fp.zeta(26), 1.0000000149015548284)
+ assert ae(fp.zeta(27), 1.0000000074507117898)
+ assert ae(fp.zeta(28), 1.0000000037253340248)
+ assert ae(fp.zeta(27.1), 1.000000006951755045)
+ assert ae(fp.zeta(32.7), 1.0000000001433243232)
+ assert ae(fp.zeta(100), 1.0)
+ assert ae(fp.altzeta(3.5), 0.92755357777394803511)
+ assert ae(fp.altzeta(1), 0.69314718055994530942)
+ assert ae(fp.altzeta(2), 0.82246703342411321824)
+ assert ae(fp.altzeta(0), 0.5)
+ assert ae(fp.zeta(-2+3j, 1), (0.13297115587929864827 + 0.12305330040458776494j))
+ assert ae(fp.zeta(-2+3j, 5), (18.384866151867576927 - 11.377015110597711009j))
+ assert ae(fp.zeta(1.0000000001), 9999999173.1735741337)
+ assert ae(fp.zeta(0.9999999999), -9999999172.0191428039)
+ assert ae(fp.zeta(1+0.000000001j), (0.57721566490153286061 - 999999999.99999993765j))
+ assert ae(fp.primezeta(2.5+4j), (-0.16922458243438033385 - 0.010847965298387727811j))
+ assert ae(fp.primezeta(4), 0.076993139764246844943)
+ assert ae(fp.riemannr(3.7), 2.3034079839110855717)
+ assert ae(fp.riemannr(8), 3.9011860449341499474)
+ assert ae(fp.riemannr(3+4j), (2.2369653314259991796 + 1.6339943856990281694j))
+
+def test_fp_hyp2f1():
+ assert ae(fp.hyp2f1(1, (3,2), 3.25, 5.0), (-0.46600275923108143059 - 0.74393667908854842325j))
+ assert ae(fp.hyp2f1(1+1j, (3,2), 3.25, 5.0), (-5.9208875603806515987 - 2.3813557707889590686j))
+ assert ae(fp.hyp2f1(1+1j, (3,2), 3.25, 2+3j), (0.17174552030925080445 + 0.19589781970539389999j))
+
+def test_fp_erf():
+ assert fp.erf(2) == fp.erf(2.0) == fp.erf(2.0+0.0j)
+ assert fp.erf(fp.inf) == 1.0
+ assert fp.erf(fp.ninf) == -1.0
+ assert ae(fp.erf(0), 0.0)
+ assert ae(fp.erf(-0), -0.0)
+ assert ae(fp.erf(0.3), 0.32862675945912741619)
+ assert ae(fp.erf(-0.3), -0.32862675945912741619)
+ assert ae(fp.erf(0.9), 0.79690821242283213966)
+ assert ae(fp.erf(-0.9), -0.79690821242283213966)
+ assert ae(fp.erf(1.0), 0.84270079294971486934)
+ assert ae(fp.erf(-1.0), -0.84270079294971486934)
+ assert ae(fp.erf(1.1), 0.88020506957408172966)
+ assert ae(fp.erf(-1.1), -0.88020506957408172966)
+ assert ae(fp.erf(8.5), 1.0)
+ assert ae(fp.erf(-8.5), -1.0)
+ assert ae(fp.erf(9.1), 1.0)
+ assert ae(fp.erf(-9.1), -1.0)
+ assert ae(fp.erf(20.0), 1.0)
+ assert ae(fp.erf(-20.0), -1.0)
+ assert ae(fp.erf(10000.0), 1.0)
+ assert ae(fp.erf(-10000.0), -1.0)
+ assert ae(fp.erf(1e+50), 1.0)
+ assert ae(fp.erf(-1e+50), -1.0)
+ assert ae(fp.erf(1j), 1.650425758797542876j)
+ assert ae(fp.erf(-1j), -1.650425758797542876j)
+ assert ae(fp.erf((2+3j)), (-20.829461427614568389 + 8.6873182714701631444j))
+ assert ae(fp.erf(-(2+3j)), -(-20.829461427614568389 + 8.6873182714701631444j))
+ assert ae(fp.erf((8+9j)), (-1072004.2525062051158 + 364149.91954310255423j))
+ assert ae(fp.erf(-(8+9j)), -(-1072004.2525062051158 + 364149.91954310255423j))
+ assert fp.erfc(fp.inf) == 0.0
+ assert fp.erfc(fp.ninf) == 2.0
+ assert fp.erfc(0) == 1
+ assert fp.erfc(-0.0) == 1
+ assert fp.erfc(0+0j) == 1
+ assert ae(fp.erfc(0.3), 0.67137324054087258381)
+ assert ae(fp.erfc(-0.3), 1.3286267594591274162)
+ assert ae(fp.erfc(0.9), 0.20309178757716786034)
+ assert ae(fp.erfc(-0.9), 1.7969082124228321397)
+ assert ae(fp.erfc(1.0), 0.15729920705028513066)
+ assert ae(fp.erfc(-1.0), 1.8427007929497148693)
+ assert ae(fp.erfc(1.1), 0.11979493042591827034)
+ assert ae(fp.erfc(-1.1), 1.8802050695740817297)
+ assert ae(fp.erfc(8.5), 2.7623240713337714461e-33)
+ assert ae(fp.erfc(-8.5), 2.0)
+ assert ae(fp.erfc(9.1), 6.6969004279886077452e-38)
+ assert ae(fp.erfc(-9.1), 2.0)
+ assert ae(fp.erfc(20.0), 5.3958656116079009289e-176)
+ assert ae(fp.erfc(-20.0), 2.0)
+ assert ae(fp.erfc(10000.0), 0.0)
+ assert ae(fp.erfc(-10000.0), 2.0)
+ assert ae(fp.erfc(1e+50), 0.0)
+ assert ae(fp.erfc(-1e+50), 2.0)
+ assert ae(fp.erfc(1j), (1.0 - 1.650425758797542876j))
+ assert ae(fp.erfc(-1j), (1.0 + 1.650425758797542876j))
+ assert ae(fp.erfc((2+3j)), (21.829461427614568389 - 8.6873182714701631444j), 1e-13)
+ assert ae(fp.erfc(-(2+3j)), (-19.829461427614568389 + 8.6873182714701631444j), 1e-13)
+ assert ae(fp.erfc((8+9j)), (1072005.2525062051158 - 364149.91954310255423j))
+ assert ae(fp.erfc(-(8+9j)), (-1072003.2525062051158 + 364149.91954310255423j))
+ assert ae(fp.erfc(20+0j), (5.3958656116079009289e-176 + 0.0j))
+
+def test_fp_lambertw():
+ assert ae(fp.lambertw(0.0), 0.0)
+ assert ae(fp.lambertw(1.0), 0.567143290409783873)
+ assert ae(fp.lambertw(7.5), 1.5662309537823875394)
+ assert ae(fp.lambertw(-0.25), -0.35740295618138890307)
+ assert ae(fp.lambertw(-10.0), (1.3699809685212708156 + 2.140194527074713196j))
+ assert ae(fp.lambertw(0+0j), (0.0 + 0.0j))
+ assert ae(fp.lambertw(4+0j), (1.2021678731970429392 + 0.0j))
+ assert ae(fp.lambertw(1000.5), 5.2500227450408980127)
+ assert ae(fp.lambertw(1e100), 224.84310644511850156)
+ assert ae(fp.lambertw(-1000.0), (5.1501630246362515223 + 2.6641981432905204596j))
+ assert ae(fp.lambertw(1e-10), 9.9999999990000003645e-11)
+ assert ae(fp.lambertw(1e-10j), (1.0000000000000000728e-20 + 1.0000000000000000364e-10j))
+ assert ae(fp.lambertw(3+4j), (1.2815618061237758782 + 0.53309522202097107131j))
+ assert ae(fp.lambertw(-3-4j), (1.0750730665692549276 - 1.3251023817343588823j))
+ assert ae(fp.lambertw(10000+1000j), (7.2361526563371602186 + 0.087567810943839352034j))
+ assert ae(fp.lambertw(0.0, -1), -fp.inf)
+ assert ae(fp.lambertw(1.0, -1), (-1.5339133197935745079 - 4.3751851530618983855j))
+ assert ae(fp.lambertw(7.5, -1), (0.44125668415098614999 - 4.8039842008452390179j))
+ assert ae(fp.lambertw(-0.25, -1), -2.1532923641103496492)
+ assert ae(fp.lambertw(-10.0, -1), (1.3699809685212708156 - 2.140194527074713196j))
+ assert ae(fp.lambertw(0+0j, -1), -fp.inf)
+ assert ae(fp.lambertw(4+0j, -1), (-0.15730793189620765317 - 4.6787800704666656212j))
+ assert ae(fp.lambertw(1000.5, -1), (4.9153765415404024736 - 5.4465682700815159569j))
+ assert ae(fp.lambertw(1e100, -1), (224.84272130101601052 - 6.2553713838167244141j))
+ assert ae(fp.lambertw(-1000.0, -1), (5.1501630246362515223 - 2.6641981432905204596j))
+ assert ae(fp.lambertw(1e-10, -1), (-26.303186778379041521 - 3.2650939117038283975j))
+ assert ae(fp.lambertw(1e-10j, -1), (-26.297238779529035028 - 1.6328071613455765135j))
+ assert ae(fp.lambertw(3+4j, -1), (0.25856740686699741676 - 3.8521166861614355895j))
+ assert ae(fp.lambertw(-3-4j, -1), (-0.32028750204310768396 - 6.8801677192091972343j))
+ assert ae(fp.lambertw(10000+1000j, -1), (7.0255308742285435567 - 5.5177506835734067601j))
+ assert ae(fp.lambertw(0.0, 2), -fp.inf)
+ assert ae(fp.lambertw(1.0, 2), (-2.4015851048680028842 + 10.776299516115070898j))
+ assert ae(fp.lambertw(7.5, 2), (-0.38003357962843791529 + 10.960916473368746184j))
+ assert ae(fp.lambertw(-0.25, 2), (-4.0558735269061511898 + 13.852334658567271386j))
+ assert ae(fp.lambertw(-10.0, 2), (-0.34479123764318858696 + 14.112740596763592363j))
+ assert ae(fp.lambertw(0+0j, 2), -fp.inf)
+ assert ae(fp.lambertw(4+0j, 2), (-1.0070343323804262788 + 10.903476551861683082j))
+ assert ae(fp.lambertw(1000.5, 2), (4.4076185165459395295 + 11.365524591091402177j))
+ assert ae(fp.lambertw(1e100, 2), (224.84156762724875878 + 12.510785262632255672j))
+ assert ae(fp.lambertw(-1000.0, 2), (4.1984245610246530756 + 14.420478573754313845j))
+ assert ae(fp.lambertw(1e-10, 2), (-26.362258095445866488 + 9.7800247407031482519j))
+ assert ae(fp.lambertw(1e-10j, 2), (-26.384250801683084252 + 11.403535950607739763j))
+ assert ae(fp.lambertw(3+4j, 2), (-0.86554679943333993562 + 11.849956798331992027j))
+ assert ae(fp.lambertw(-3-4j, 2), (-0.55792273874679112639 + 8.7173627024159324811j))
+ assert ae(fp.lambertw(10000+1000j, 2), (6.6223802254585662734 + 11.61348646825020766j))
+
+def test_fp_stress_ei_e1():
+ # Can be tightened on recent Pythons with more accurate math/cmath
+ ATOL = 1e-13
+ PTOL = 1e-12
+ v = fp.e1(1.1641532182693481445e-10)
+ assert ae(v, 22.296641293693077672, tol=ATOL)
+ assert type(v) is float
+ v = fp.e1(0.25)
+ assert ae(v, 1.0442826344437381945, tol=ATOL)
+ assert type(v) is float
+ v = fp.e1(1.0)
+ assert ae(v, 0.21938393439552027368, tol=ATOL)
+ assert type(v) is float
+ v = fp.e1(2.0)
+ assert ae(v, 0.048900510708061119567, tol=ATOL)
+ assert type(v) is float
+ v = fp.e1(5.0)
+ assert ae(v, 0.0011482955912753257973, tol=ATOL)
+ assert type(v) is float
+ v = fp.e1(20.0)
+ assert ae(v, 9.8355252906498816904e-11, tol=ATOL)
+ assert type(v) is float
+ v = fp.e1(30.0)
+ assert ae(v, 3.0215520106888125448e-15, tol=ATOL)
+ assert type(v) is float
+ v = fp.e1(40.0)
+ assert ae(v, 1.0367732614516569722e-19, tol=ATOL)
+ assert type(v) is float
+ v = fp.e1(50.0)
+ assert ae(v, 3.7832640295504590187e-24, tol=ATOL)
+ assert type(v) is float
+ v = fp.e1(80.0)
+ assert ae(v, 2.2285432586884729112e-37, tol=ATOL)
+ assert type(v) is float
+ v = fp.e1((1.1641532182693481445e-10 + 0.0j))
+ assert ae(v, (22.296641293693077672 + 0.0j), tol=ATOL)
+ assert ae(v.real, 22.296641293693077672, tol=PTOL)
+ assert v.imag == 0
+ v = fp.e1((0.25 + 0.0j))
+ assert ae(v, (1.0442826344437381945 + 0.0j), tol=ATOL)
+ assert ae(v.real, 1.0442826344437381945, tol=PTOL)
+ assert v.imag == 0
+ v = fp.e1((1.0 + 0.0j))
+ assert ae(v, (0.21938393439552027368 + 0.0j), tol=ATOL)
+ assert ae(v.real, 0.21938393439552027368, tol=PTOL)
+ assert v.imag == 0
+ v = fp.e1((2.0 + 0.0j))
+ assert ae(v, (0.048900510708061119567 + 0.0j), tol=ATOL)
+ assert ae(v.real, 0.048900510708061119567, tol=PTOL)
+ assert v.imag == 0
+ v = fp.e1((5.0 + 0.0j))
+ assert ae(v, (0.0011482955912753257973 + 0.0j), tol=ATOL)
+ assert ae(v.real, 0.0011482955912753257973, tol=PTOL)
+ assert v.imag == 0
+ v = fp.e1((20.0 + 0.0j))
+ assert ae(v, (9.8355252906498816904e-11 + 0.0j), tol=ATOL)
+ assert ae(v.real, 9.8355252906498816904e-11, tol=PTOL)
+ assert v.imag == 0
+ v = fp.e1((30.0 + 0.0j))
+ assert ae(v, (3.0215520106888125448e-15 + 0.0j), tol=ATOL)
+ assert ae(v.real, 3.0215520106888125448e-15, tol=PTOL)
+ assert v.imag == 0
+ v = fp.e1((40.0 + 0.0j))
+ assert ae(v, (1.0367732614516569722e-19 + 0.0j), tol=ATOL)
+ assert ae(v.real, 1.0367732614516569722e-19, tol=PTOL)
+ assert v.imag == 0
+ v = fp.e1((50.0 + 0.0j))
+ assert ae(v, (3.7832640295504590187e-24 + 0.0j), tol=ATOL)
+ assert ae(v.real, 3.7832640295504590187e-24, tol=PTOL)
+ assert v.imag == 0
+ v = fp.e1((80.0 + 0.0j))
+ assert ae(v, (2.2285432586884729112e-37 + 0.0j), tol=ATOL)
+ assert ae(v.real, 2.2285432586884729112e-37, tol=PTOL)
+ assert v.imag == 0
+ v = fp.e1((4.6566128730773925781e-10 + 1.1641532182693481445e-10j))
+ assert ae(v, (20.880034622014215597 - 0.24497866301044883237j), tol=ATOL)
+ assert ae(v.real, 20.880034622014215597, tol=PTOL)
+ assert ae(v.imag, -0.24497866301044883237, tol=PTOL)
+ v = fp.e1((1.0 + 0.25j))
+ assert ae(v, (0.19731063945004229095 - 0.087366045774299963672j), tol=ATOL)
+ assert ae(v.real, 0.19731063945004229095, tol=PTOL)
+ assert ae(v.imag, -0.087366045774299963672, tol=PTOL)
+ v = fp.e1((4.0 + 1.0j))
+ assert ae(v, (0.0013106173980145506944 - 0.0034542480199350626699j), tol=ATOL)
+ assert ae(v.real, 0.0013106173980145506944, tol=PTOL)
+ assert ae(v.imag, -0.0034542480199350626699, tol=PTOL)
+ v = fp.e1((8.0 + 2.0j))
+ assert ae(v, (-0.000022278049065270225945 - 0.000029191940456521555288j), tol=ATOL)
+ assert ae(v.real, -0.000022278049065270225945, tol=PTOL)
+ assert ae(v.imag, -0.000029191940456521555288, tol=PTOL)
+ v = fp.e1((20.0 + 5.0j))
+ assert ae(v, (4.7711374515765346894e-11 + 8.2902652405126947359e-11j), tol=ATOL)
+ assert ae(v.real, 4.7711374515765346894e-11, tol=PTOL)
+ assert ae(v.imag, 8.2902652405126947359e-11, tol=PTOL)
+ v = fp.e1((80.0 + 20.0j))
+ assert ae(v, (3.8353473865788235787e-38 - 2.129247592349605139e-37j), tol=ATOL)
+ assert ae(v.real, 3.8353473865788235787e-38, tol=PTOL)
+ assert ae(v.imag, -2.129247592349605139e-37, tol=PTOL)
+ v = fp.e1((120.0 + 30.0j))
+ assert ae(v, (2.3836002337480334716e-55 + 5.6704043587126198306e-55j), tol=ATOL)
+ assert ae(v.real, 2.3836002337480334716e-55, tol=PTOL)
+ assert ae(v.imag, 5.6704043587126198306e-55, tol=PTOL)
+ v = fp.e1((160.0 + 40.0j))
+ assert ae(v, (-1.6238022898654510661e-72 - 1.104172355572287367e-72j), tol=ATOL)
+ assert ae(v.real, -1.6238022898654510661e-72, tol=PTOL)
+ assert ae(v.imag, -1.104172355572287367e-72, tol=PTOL)
+ v = fp.e1((200.0 + 50.0j))
+ assert ae(v, (6.6800061461666228487e-90 + 1.4473816083541016115e-91j), tol=ATOL)
+ assert ae(v.real, 6.6800061461666228487e-90, tol=PTOL)
+ assert ae(v.imag, 1.4473816083541016115e-91, tol=PTOL)
+ v = fp.e1((320.0 + 80.0j))
+ assert ae(v, (4.2737871527778786157e-143 + 3.1789935525785660314e-142j), tol=ATOL)
+ assert ae(v.real, 4.2737871527778786157e-143, tol=PTOL)
+ assert ae(v.imag, 3.1789935525785660314e-142, tol=PTOL)
+ v = fp.e1((1.1641532182693481445e-10 + 1.1641532182693481445e-10j))
+ assert ae(v, (21.950067703413105017 - 0.7853981632810329878j), tol=ATOL)
+ assert ae(v.real, 21.950067703413105017, tol=PTOL)
+ assert ae(v.imag, -0.7853981632810329878, tol=PTOL)
+ v = fp.e1((0.25 + 0.25j))
+ assert ae(v, (0.71092525792923287894 - 0.56491812441304194711j), tol=ATOL)
+ assert ae(v.real, 0.71092525792923287894, tol=PTOL)
+ assert ae(v.imag, -0.56491812441304194711, tol=PTOL)
+ v = fp.e1((1.0 + 1.0j))
+ assert ae(v, (0.00028162445198141832551 - 0.17932453503935894015j), tol=ATOL)
+ assert ae(v.real, 0.00028162445198141832551, tol=PTOL)
+ assert ae(v.imag, -0.17932453503935894015, tol=PTOL)
+ v = fp.e1((2.0 + 2.0j))
+ assert ae(v, (-0.033767089606562004246 - 0.018599414169750541925j), tol=ATOL)
+ assert ae(v.real, -0.033767089606562004246, tol=PTOL)
+ assert ae(v.imag, -0.018599414169750541925, tol=PTOL)
+ v = fp.e1((5.0 + 5.0j))
+ assert ae(v, (0.0007266506660356393891 + 0.00047102780163522245054j), tol=ATOL)
+ assert ae(v.real, 0.0007266506660356393891, tol=PTOL)
+ assert ae(v.imag, 0.00047102780163522245054, tol=PTOL)
+ v = fp.e1((20.0 + 20.0j))
+ assert ae(v, (-2.3824537449367396579e-11 - 6.6969873156525615158e-11j), tol=ATOL)
+ assert ae(v.real, -2.3824537449367396579e-11, tol=PTOL)
+ assert ae(v.imag, -6.6969873156525615158e-11, tol=PTOL)
+ v = fp.e1((30.0 + 30.0j))
+ assert ae(v, (1.7316045841744061617e-15 + 1.3065678019487308689e-15j), tol=ATOL)
+ assert ae(v.real, 1.7316045841744061617e-15, tol=PTOL)
+ assert ae(v.imag, 1.3065678019487308689e-15, tol=PTOL)
+ v = fp.e1((40.0 + 40.0j))
+ assert ae(v, (-7.4001043002899232182e-20 - 4.991847855336816304e-21j), tol=ATOL)
+ assert ae(v.real, -7.4001043002899232182e-20, tol=PTOL)
+ assert ae(v.imag, -4.991847855336816304e-21, tol=PTOL)
+ v = fp.e1((50.0 + 50.0j))
+ assert ae(v, (2.3566128324644641219e-24 - 1.3188326726201614778e-24j), tol=ATOL)
+ assert ae(v.real, 2.3566128324644641219e-24, tol=PTOL)
+ assert ae(v.imag, -1.3188326726201614778e-24, tol=PTOL)
+ v = fp.e1((80.0 + 80.0j))
+ assert ae(v, (9.8279750572186526673e-38 + 1.243952841288868831e-37j), tol=ATOL)
+ assert ae(v.real, 9.8279750572186526673e-38, tol=PTOL)
+ assert ae(v.imag, 1.243952841288868831e-37, tol=PTOL)
+ v = fp.e1((1.1641532182693481445e-10 + 4.6566128730773925781e-10j))
+ assert ae(v, (20.880034621664969632 - 1.3258176632023711778j), tol=ATOL)
+ assert ae(v.real, 20.880034621664969632, tol=PTOL)
+ assert ae(v.imag, -1.3258176632023711778, tol=PTOL)
+ v = fp.e1((0.25 + 1.0j))
+ assert ae(v, (-0.16868306393667788761 - 0.4858011885947426971j), tol=ATOL)
+ assert ae(v.real, -0.16868306393667788761, tol=PTOL)
+ assert ae(v.imag, -0.4858011885947426971, tol=PTOL)
+ v = fp.e1((1.0 + 4.0j))
+ assert ae(v, (0.03373591813926547318 + 0.073523452241083821877j), tol=ATOL)
+ assert ae(v.real, 0.03373591813926547318, tol=PTOL)
+ assert ae(v.imag, 0.073523452241083821877, tol=PTOL)
+ v = fp.e1((2.0 + 8.0j))
+ assert ae(v, (-0.015392833434733785143 - 0.0031747121557605415914j), tol=ATOL)
+ assert ae(v.real, -0.015392833434733785143, tol=PTOL)
+ assert ae(v.imag, -0.0031747121557605415914, tol=PTOL)
+ v = fp.e1((5.0 + 20.0j))
+ assert ae(v, (-0.00024419662286542966525 - 0.00021008322966152755674j), tol=ATOL)
+ assert ae(v.real, -0.00024419662286542966525, tol=PTOL)
+ assert ae(v.imag, -0.00021008322966152755674, tol=PTOL)
+ v = fp.e1((20.0 + 80.0j))
+ assert ae(v, (2.3255552781051330088e-11 + 8.9463918891349438007e-12j), tol=ATOL)
+ assert ae(v.real, 2.3255552781051330088e-11, tol=PTOL)
+ assert ae(v.imag, 8.9463918891349438007e-12, tol=PTOL)
+ v = fp.e1((30.0 + 120.0j))
+ assert ae(v, (-2.7068919097124652332e-16 - 7.0477762411705130239e-16j), tol=ATOL)
+ assert ae(v.real, -2.7068919097124652332e-16, tol=PTOL)
+ assert ae(v.imag, -7.0477762411705130239e-16, tol=PTOL)
+ v = fp.e1((40.0 + 160.0j))
+ assert ae(v, (-1.1695597827678024687e-20 + 2.2907401455645736661e-20j), tol=ATOL)
+ assert ae(v.real, -1.1695597827678024687e-20, tol=PTOL)
+ assert ae(v.imag, 2.2907401455645736661e-20, tol=PTOL)
+ v = fp.e1((50.0 + 200.0j))
+ assert ae(v, (9.0323746914410162531e-25 - 2.3950601790033530935e-25j), tol=ATOL)
+ assert ae(v.real, 9.0323746914410162531e-25, tol=PTOL)
+ assert ae(v.imag, -2.3950601790033530935e-25, tol=PTOL)
+ v = fp.e1((80.0 + 320.0j))
+ assert ae(v, (3.4819106748728063576e-38 - 4.215653005615772724e-38j), tol=ATOL)
+ assert ae(v.real, 3.4819106748728063576e-38, tol=PTOL)
+ assert ae(v.imag, -4.215653005615772724e-38, tol=PTOL)
+ v = fp.e1((0.0 + 1.1641532182693481445e-10j))
+ assert ae(v, (22.29664129357666235 - 1.5707963266784812974j), tol=ATOL)
+ assert ae(v.real, 22.29664129357666235, tol=PTOL)
+ assert ae(v.imag, -1.5707963266784812974, tol=PTOL)
+ v = fp.e1((0.0 + 0.25j))
+ assert ae(v, (0.82466306258094565309 - 1.3216627564751394551j), tol=ATOL)
+ assert ae(v.real, 0.82466306258094565309, tol=PTOL)
+ assert ae(v.imag, -1.3216627564751394551, tol=PTOL)
+ v = fp.e1((0.0 + 1.0j))
+ assert ae(v, (-0.33740392290096813466 - 0.62471325642771360429j), tol=ATOL)
+ assert ae(v.real, -0.33740392290096813466, tol=PTOL)
+ assert ae(v.imag, -0.62471325642771360429, tol=PTOL)
+ v = fp.e1((0.0 + 2.0j))
+ assert ae(v, (-0.4229808287748649957 + 0.034616650007798229345j), tol=ATOL)
+ assert ae(v.real, -0.4229808287748649957, tol=PTOL)
+ assert ae(v.imag, 0.034616650007798229345, tol=PTOL)
+ v = fp.e1((0.0 + 5.0j))
+ assert ae(v, (0.19002974965664387862 - 0.020865081850222481957j), tol=ATOL)
+ assert ae(v.real, 0.19002974965664387862, tol=PTOL)
+ assert ae(v.imag, -0.020865081850222481957, tol=PTOL)
+ v = fp.e1((0.0 + 20.0j))
+ assert ae(v, (-0.04441982084535331654 - 0.022554625751456779068j), tol=ATOL)
+ assert ae(v.real, -0.04441982084535331654, tol=PTOL)
+ assert ae(v.imag, -0.022554625751456779068, tol=PTOL)
+ v = fp.e1((0.0 + 30.0j))
+ assert ae(v, (0.033032417282071143779 - 0.0040397867645455082476j), tol=ATOL)
+ assert ae(v.real, 0.033032417282071143779, tol=PTOL)
+ assert ae(v.imag, -0.0040397867645455082476, tol=PTOL)
+ v = fp.e1((0.0 + 40.0j))
+ assert ae(v, (-0.019020007896208766962 + 0.016188792559887887544j), tol=ATOL)
+ assert ae(v.real, -0.019020007896208766962, tol=PTOL)
+ assert ae(v.imag, 0.016188792559887887544, tol=PTOL)
+ v = fp.e1((0.0 + 50.0j))
+ assert ae(v, (0.0056283863241163054402 - 0.019179254308960724503j), tol=ATOL)
+ assert ae(v.real, 0.0056283863241163054402, tol=PTOL)
+ assert ae(v.imag, -0.019179254308960724503, tol=PTOL)
+ v = fp.e1((0.0 + 80.0j))
+ assert ae(v, (0.012402501155070958192 + 0.0015345601175906961199j), tol=ATOL)
+ assert ae(v.real, 0.012402501155070958192, tol=PTOL)
+ assert ae(v.imag, 0.0015345601175906961199, tol=PTOL)
+ v = fp.e1((-1.1641532182693481445e-10 + 4.6566128730773925781e-10j))
+ assert ae(v, (20.880034621432138988 - 1.8157749894560994861j), tol=ATOL)
+ assert ae(v.real, 20.880034621432138988, tol=PTOL)
+ assert ae(v.imag, -1.8157749894560994861, tol=PTOL)
+ v = fp.e1((-0.25 + 1.0j))
+ assert ae(v, (-0.59066621214766308594 - 0.74474454765205036972j), tol=ATOL)
+ assert ae(v.real, -0.59066621214766308594, tol=PTOL)
+ assert ae(v.imag, -0.74474454765205036972, tol=PTOL)
+ v = fp.e1((-1.0 + 4.0j))
+ assert ae(v, (0.49739047283060471093 + 0.41543605404038863174j), tol=ATOL)
+ assert ae(v.real, 0.49739047283060471093, tol=PTOL)
+ assert ae(v.imag, 0.41543605404038863174, tol=PTOL)
+ v = fp.e1((-2.0 + 8.0j))
+ assert ae(v, (-0.8705211147733730969 + 0.24099328498605539667j), tol=ATOL)
+ assert ae(v.real, -0.8705211147733730969, tol=PTOL)
+ assert ae(v.imag, 0.24099328498605539667, tol=PTOL)
+ v = fp.e1((-5.0 + 20.0j))
+ assert ae(v, (-7.0789514293925893007 - 1.6102177171960790536j), tol=ATOL)
+ assert ae(v.real, -7.0789514293925893007, tol=PTOL)
+ assert ae(v.imag, -1.6102177171960790536, tol=PTOL)
+ v = fp.e1((-20.0 + 80.0j))
+ assert ae(v, (5855431.4907298084434 - 720920.93315409165707j), tol=ATOL)
+ assert ae(v.real, 5855431.4907298084434, tol=PTOL)
+ assert ae(v.imag, -720920.93315409165707, tol=PTOL)
+ v = fp.e1((-30.0 + 120.0j))
+ assert ae(v, (-65402491644.703470747 - 56697658399.657460294j), tol=ATOL)
+ assert ae(v.real, -65402491644.703470747, tol=PTOL)
+ assert ae(v.imag, -56697658399.657460294, tol=PTOL)
+ v = fp.e1((-40.0 + 160.0j))
+ assert ae(v, (25504929379604.776769 + 1429035198630573.2463j), tol=ATOL)
+ assert ae(v.real, 25504929379604.776769, tol=PTOL)
+ assert ae(v.imag, 1429035198630573.2463, tol=PTOL)
+ v = fp.e1((-50.0 + 200.0j))
+ assert ae(v, (18437746526988116954.0 - 17146362239046152345.0j), tol=ATOL)
+ assert ae(v.real, 18437746526988116954.0, tol=PTOL)
+ assert ae(v.imag, -17146362239046152345.0, tol=PTOL)
+ v = fp.e1((-80.0 + 320.0j))
+ assert ae(v, (3.3464697299634526706e+31 - 1.6473152633843023919e+32j), tol=ATOL)
+ assert ae(v.real, 3.3464697299634526706e+31, tol=PTOL)
+ assert ae(v.imag, -1.6473152633843023919e+32, tol=PTOL)
+ v = fp.e1((-4.6566128730773925781e-10 + 1.1641532182693481445e-10j))
+ assert ae(v, (20.880034621082893023 - 2.8966139903465137624j), tol=ATOL)
+ assert ae(v.real, 20.880034621082893023, tol=PTOL)
+ assert ae(v.imag, -2.8966139903465137624, tol=PTOL)
+ v = fp.e1((-1.0 + 0.25j))
+ assert ae(v, (-1.8942716983721074932 - 2.4689102827070540799j), tol=ATOL)
+ assert ae(v.real, -1.8942716983721074932, tol=PTOL)
+ assert ae(v.imag, -2.4689102827070540799, tol=PTOL)
+ v = fp.e1((-4.0 + 1.0j))
+ assert ae(v, (-14.806699492675420438 + 9.1384225230837893776j), tol=ATOL)
+ assert ae(v.real, -14.806699492675420438, tol=PTOL)
+ assert ae(v.imag, 9.1384225230837893776, tol=PTOL)
+ v = fp.e1((-8.0 + 2.0j))
+ assert ae(v, (54.633252667426386294 + 413.20318163814670688j), tol=ATOL)
+ assert ae(v.real, 54.633252667426386294, tol=PTOL)
+ assert ae(v.imag, 413.20318163814670688, tol=PTOL)
+ v = fp.e1((-20.0 + 5.0j))
+ assert ae(v, (-711836.97165402624643 - 24745250.939695900956j), tol=ATOL)
+ assert ae(v.real, -711836.97165402624643, tol=PTOL)
+ assert ae(v.imag, -24745250.939695900956, tol=PTOL)
+ v = fp.e1((-80.0 + 20.0j))
+ assert ae(v, (-4.2139911108612653091e+32 + 5.3367124741918251637e+32j), tol=ATOL)
+ assert ae(v.real, -4.2139911108612653091e+32, tol=PTOL)
+ assert ae(v.imag, 5.3367124741918251637e+32, tol=PTOL)
+ v = fp.e1((-120.0 + 30.0j))
+ assert ae(v, (9.7760616203707508892e+48 - 1.058257682317195792e+50j), tol=ATOL)
+ assert ae(v.real, 9.7760616203707508892e+48, tol=PTOL)
+ assert ae(v.imag, -1.058257682317195792e+50, tol=PTOL)
+ v = fp.e1((-160.0 + 40.0j))
+ assert ae(v, (8.7065541466623638861e+66 + 1.6577106725141739889e+67j), tol=ATOL)
+ assert ae(v.real, 8.7065541466623638861e+66, tol=PTOL)
+ assert ae(v.imag, 1.6577106725141739889e+67, tol=PTOL)
+ v = fp.e1((-200.0 + 50.0j))
+ assert ae(v, (-3.070744996327018106e+84 - 1.7243244846769415903e+84j), tol=ATOL)
+ assert ae(v.real, -3.070744996327018106e+84, tol=PTOL)
+ assert ae(v.imag, -1.7243244846769415903e+84, tol=PTOL)
+ v = fp.e1((-320.0 + 80.0j))
+ assert ae(v, (9.9960598637998647276e+135 - 2.6855081527595608863e+136j), tol=ATOL)
+ assert ae(v.real, 9.9960598637998647276e+135, tol=PTOL)
+ assert ae(v.imag, -2.6855081527595608863e+136, tol=PTOL)
+ v = fp.e1(-1.1641532182693481445e-10)
+ assert ae(v, (22.296641293460247028 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, 22.296641293460247028, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1(-0.25)
+ assert ae(v, (0.54254326466191372953 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, 0.54254326466191372953, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1(-1.0)
+ assert ae(v, (-1.8951178163559367555 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -1.8951178163559367555, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1(-2.0)
+ assert ae(v, (-4.9542343560018901634 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -4.9542343560018901634, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1(-5.0)
+ assert ae(v, (-40.185275355803177455 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -40.185275355803177455, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1(-20.0)
+ assert ae(v, (-25615652.66405658882 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -25615652.66405658882, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1(-30.0)
+ assert ae(v, (-368973209407.27419706 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -368973209407.27419706, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1(-40.0)
+ assert ae(v, (-6039718263611241.5784 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -6039718263611241.5784, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1(-50.0)
+ assert ae(v, (-1.0585636897131690963e+20 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -1.0585636897131690963e+20, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1(-80.0)
+ assert ae(v, (-7.0146000049047999696e+32 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -7.0146000049047999696e+32, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1((-1.1641532182693481445e-10 + 0.0j))
+ assert ae(v, (22.296641293460247028 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, 22.296641293460247028, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1((-0.25 + 0.0j))
+ assert ae(v, (0.54254326466191372953 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, 0.54254326466191372953, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1((-1.0 + 0.0j))
+ assert ae(v, (-1.8951178163559367555 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -1.8951178163559367555, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1((-2.0 + 0.0j))
+ assert ae(v, (-4.9542343560018901634 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -4.9542343560018901634, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1((-5.0 + 0.0j))
+ assert ae(v, (-40.185275355803177455 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -40.185275355803177455, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1((-20.0 + 0.0j))
+ assert ae(v, (-25615652.66405658882 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -25615652.66405658882, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1((-30.0 + 0.0j))
+ assert ae(v, (-368973209407.27419706 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -368973209407.27419706, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1((-40.0 + 0.0j))
+ assert ae(v, (-6039718263611241.5784 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -6039718263611241.5784, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1((-50.0 + 0.0j))
+ assert ae(v, (-1.0585636897131690963e+20 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -1.0585636897131690963e+20, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1((-80.0 + 0.0j))
+ assert ae(v, (-7.0146000049047999696e+32 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -7.0146000049047999696e+32, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.e1((-4.6566128730773925781e-10 - 1.1641532182693481445e-10j))
+ assert ae(v, (20.880034621082893023 + 2.8966139903465137624j), tol=ATOL)
+ assert ae(v.real, 20.880034621082893023, tol=PTOL)
+ assert ae(v.imag, 2.8966139903465137624, tol=PTOL)
+ v = fp.e1((-1.0 - 0.25j))
+ assert ae(v, (-1.8942716983721074932 + 2.4689102827070540799j), tol=ATOL)
+ assert ae(v.real, -1.8942716983721074932, tol=PTOL)
+ assert ae(v.imag, 2.4689102827070540799, tol=PTOL)
+ v = fp.e1((-4.0 - 1.0j))
+ assert ae(v, (-14.806699492675420438 - 9.1384225230837893776j), tol=ATOL)
+ assert ae(v.real, -14.806699492675420438, tol=PTOL)
+ assert ae(v.imag, -9.1384225230837893776, tol=PTOL)
+ v = fp.e1((-8.0 - 2.0j))
+ assert ae(v, (54.633252667426386294 - 413.20318163814670688j), tol=ATOL)
+ assert ae(v.real, 54.633252667426386294, tol=PTOL)
+ assert ae(v.imag, -413.20318163814670688, tol=PTOL)
+ v = fp.e1((-20.0 - 5.0j))
+ assert ae(v, (-711836.97165402624643 + 24745250.939695900956j), tol=ATOL)
+ assert ae(v.real, -711836.97165402624643, tol=PTOL)
+ assert ae(v.imag, 24745250.939695900956, tol=PTOL)
+ v = fp.e1((-80.0 - 20.0j))
+ assert ae(v, (-4.2139911108612653091e+32 - 5.3367124741918251637e+32j), tol=ATOL)
+ assert ae(v.real, -4.2139911108612653091e+32, tol=PTOL)
+ assert ae(v.imag, -5.3367124741918251637e+32, tol=PTOL)
+ v = fp.e1((-120.0 - 30.0j))
+ assert ae(v, (9.7760616203707508892e+48 + 1.058257682317195792e+50j), tol=ATOL)
+ assert ae(v.real, 9.7760616203707508892e+48, tol=PTOL)
+ assert ae(v.imag, 1.058257682317195792e+50, tol=PTOL)
+ v = fp.e1((-160.0 - 40.0j))
+ assert ae(v, (8.7065541466623638861e+66 - 1.6577106725141739889e+67j), tol=ATOL)
+ assert ae(v.real, 8.7065541466623638861e+66, tol=PTOL)
+ assert ae(v.imag, -1.6577106725141739889e+67, tol=PTOL)
+ v = fp.e1((-200.0 - 50.0j))
+ assert ae(v, (-3.070744996327018106e+84 + 1.7243244846769415903e+84j), tol=ATOL)
+ assert ae(v.real, -3.070744996327018106e+84, tol=PTOL)
+ assert ae(v.imag, 1.7243244846769415903e+84, tol=PTOL)
+ v = fp.e1((-320.0 - 80.0j))
+ assert ae(v, (9.9960598637998647276e+135 + 2.6855081527595608863e+136j), tol=ATOL)
+ assert ae(v.real, 9.9960598637998647276e+135, tol=PTOL)
+ assert ae(v.imag, 2.6855081527595608863e+136, tol=PTOL)
+ v = fp.e1((-1.1641532182693481445e-10 - 1.1641532182693481445e-10j))
+ assert ae(v, (21.950067703180274374 + 2.356194490075929607j), tol=ATOL)
+ assert ae(v.real, 21.950067703180274374, tol=PTOL)
+ assert ae(v.imag, 2.356194490075929607, tol=PTOL)
+ v = fp.e1((-0.25 - 0.25j))
+ assert ae(v, (0.21441047326710323254 + 2.0732153554307936389j), tol=ATOL)
+ assert ae(v.real, 0.21441047326710323254, tol=PTOL)
+ assert ae(v.imag, 2.0732153554307936389, tol=PTOL)
+ v = fp.e1((-1.0 - 1.0j))
+ assert ae(v, (-1.7646259855638540684 + 0.7538228020792708192j), tol=ATOL)
+ assert ae(v.real, -1.7646259855638540684, tol=PTOL)
+ assert ae(v.imag, 0.7538228020792708192, tol=PTOL)
+ v = fp.e1((-2.0 - 2.0j))
+ assert ae(v, (-1.8920781621855474089 - 2.1753697842428647236j), tol=ATOL)
+ assert ae(v.real, -1.8920781621855474089, tol=PTOL)
+ assert ae(v.imag, -2.1753697842428647236, tol=PTOL)
+ v = fp.e1((-5.0 - 5.0j))
+ assert ae(v, (13.470936071475245856 + 18.464085049321024206j), tol=ATOL)
+ assert ae(v.real, 13.470936071475245856, tol=PTOL)
+ assert ae(v.imag, 18.464085049321024206, tol=PTOL)
+ v = fp.e1((-20.0 - 20.0j))
+ assert ae(v, (-16589317.398788971896 - 5831702.3296441771206j), tol=ATOL)
+ assert ae(v.real, -16589317.398788971896, tol=PTOL)
+ assert ae(v.imag, -5831702.3296441771206, tol=PTOL)
+ v = fp.e1((-30.0 - 30.0j))
+ assert ae(v, (154596484273.69322527 + 204179357837.41389696j), tol=ATOL)
+ assert ae(v.real, 154596484273.69322527, tol=PTOL)
+ assert ae(v.imag, 204179357837.41389696, tol=PTOL)
+ v = fp.e1((-40.0 - 40.0j))
+ assert ae(v, (-287512180321448.45408 - 4203502407932314.974j), tol=ATOL)
+ assert ae(v.real, -287512180321448.45408, tol=PTOL)
+ assert ae(v.imag, -4203502407932314.974, tol=PTOL)
+ v = fp.e1((-50.0 - 50.0j))
+ assert ae(v, (-36128528616649268826.0 + 64648801861338741963.0j), tol=ATOL)
+ assert ae(v.real, -36128528616649268826.0, tol=PTOL)
+ assert ae(v.imag, 64648801861338741963.0, tol=PTOL)
+ v = fp.e1((-80.0 - 80.0j))
+ assert ae(v, (3.8674816337930010217e+32 + 3.0540709639658071041e+32j), tol=ATOL)
+ assert ae(v.real, 3.8674816337930010217e+32, tol=PTOL)
+ assert ae(v.imag, 3.0540709639658071041e+32, tol=PTOL)
+ v = fp.e1((-1.1641532182693481445e-10 - 4.6566128730773925781e-10j))
+ assert ae(v, (20.880034621432138988 + 1.8157749894560994861j), tol=ATOL)
+ assert ae(v.real, 20.880034621432138988, tol=PTOL)
+ assert ae(v.imag, 1.8157749894560994861, tol=PTOL)
+ v = fp.e1((-0.25 - 1.0j))
+ assert ae(v, (-0.59066621214766308594 + 0.74474454765205036972j), tol=ATOL)
+ assert ae(v.real, -0.59066621214766308594, tol=PTOL)
+ assert ae(v.imag, 0.74474454765205036972, tol=PTOL)
+ v = fp.e1((-1.0 - 4.0j))
+ assert ae(v, (0.49739047283060471093 - 0.41543605404038863174j), tol=ATOL)
+ assert ae(v.real, 0.49739047283060471093, tol=PTOL)
+ assert ae(v.imag, -0.41543605404038863174, tol=PTOL)
+ v = fp.e1((-2.0 - 8.0j))
+ assert ae(v, (-0.8705211147733730969 - 0.24099328498605539667j), tol=ATOL)
+ assert ae(v.real, -0.8705211147733730969, tol=PTOL)
+ assert ae(v.imag, -0.24099328498605539667, tol=PTOL)
+ v = fp.e1((-5.0 - 20.0j))
+ assert ae(v, (-7.0789514293925893007 + 1.6102177171960790536j), tol=ATOL)
+ assert ae(v.real, -7.0789514293925893007, tol=PTOL)
+ assert ae(v.imag, 1.6102177171960790536, tol=PTOL)
+ v = fp.e1((-20.0 - 80.0j))
+ assert ae(v, (5855431.4907298084434 + 720920.93315409165707j), tol=ATOL)
+ assert ae(v.real, 5855431.4907298084434, tol=PTOL)
+ assert ae(v.imag, 720920.93315409165707, tol=PTOL)
+ v = fp.e1((-30.0 - 120.0j))
+ assert ae(v, (-65402491644.703470747 + 56697658399.657460294j), tol=ATOL)
+ assert ae(v.real, -65402491644.703470747, tol=PTOL)
+ assert ae(v.imag, 56697658399.657460294, tol=PTOL)
+ v = fp.e1((-40.0 - 160.0j))
+ assert ae(v, (25504929379604.776769 - 1429035198630573.2463j), tol=ATOL)
+ assert ae(v.real, 25504929379604.776769, tol=PTOL)
+ assert ae(v.imag, -1429035198630573.2463, tol=PTOL)
+ v = fp.e1((-50.0 - 200.0j))
+ assert ae(v, (18437746526988116954.0 + 17146362239046152345.0j), tol=ATOL)
+ assert ae(v.real, 18437746526988116954.0, tol=PTOL)
+ assert ae(v.imag, 17146362239046152345.0, tol=PTOL)
+ v = fp.e1((-80.0 - 320.0j))
+ assert ae(v, (3.3464697299634526706e+31 + 1.6473152633843023919e+32j), tol=ATOL)
+ assert ae(v.real, 3.3464697299634526706e+31, tol=PTOL)
+ assert ae(v.imag, 1.6473152633843023919e+32, tol=PTOL)
+ v = fp.e1((0.0 - 1.1641532182693481445e-10j))
+ assert ae(v, (22.29664129357666235 + 1.5707963266784812974j), tol=ATOL)
+ assert ae(v.real, 22.29664129357666235, tol=PTOL)
+ assert ae(v.imag, 1.5707963266784812974, tol=PTOL)
+ v = fp.e1((0.0 - 0.25j))
+ assert ae(v, (0.82466306258094565309 + 1.3216627564751394551j), tol=ATOL)
+ assert ae(v.real, 0.82466306258094565309, tol=PTOL)
+ assert ae(v.imag, 1.3216627564751394551, tol=PTOL)
+ v = fp.e1((0.0 - 1.0j))
+ assert ae(v, (-0.33740392290096813466 + 0.62471325642771360429j), tol=ATOL)
+ assert ae(v.real, -0.33740392290096813466, tol=PTOL)
+ assert ae(v.imag, 0.62471325642771360429, tol=PTOL)
+ v = fp.e1((0.0 - 2.0j))
+ assert ae(v, (-0.4229808287748649957 - 0.034616650007798229345j), tol=ATOL)
+ assert ae(v.real, -0.4229808287748649957, tol=PTOL)
+ assert ae(v.imag, -0.034616650007798229345, tol=PTOL)
+ v = fp.e1((0.0 - 5.0j))
+ assert ae(v, (0.19002974965664387862 + 0.020865081850222481957j), tol=ATOL)
+ assert ae(v.real, 0.19002974965664387862, tol=PTOL)
+ assert ae(v.imag, 0.020865081850222481957, tol=PTOL)
+ v = fp.e1((0.0 - 20.0j))
+ assert ae(v, (-0.04441982084535331654 + 0.022554625751456779068j), tol=ATOL)
+ assert ae(v.real, -0.04441982084535331654, tol=PTOL)
+ assert ae(v.imag, 0.022554625751456779068, tol=PTOL)
+ v = fp.e1((0.0 - 30.0j))
+ assert ae(v, (0.033032417282071143779 + 0.0040397867645455082476j), tol=ATOL)
+ assert ae(v.real, 0.033032417282071143779, tol=PTOL)
+ assert ae(v.imag, 0.0040397867645455082476, tol=PTOL)
+ v = fp.e1((0.0 - 40.0j))
+ assert ae(v, (-0.019020007896208766962 - 0.016188792559887887544j), tol=ATOL)
+ assert ae(v.real, -0.019020007896208766962, tol=PTOL)
+ assert ae(v.imag, -0.016188792559887887544, tol=PTOL)
+ v = fp.e1((0.0 - 50.0j))
+ assert ae(v, (0.0056283863241163054402 + 0.019179254308960724503j), tol=ATOL)
+ assert ae(v.real, 0.0056283863241163054402, tol=PTOL)
+ assert ae(v.imag, 0.019179254308960724503, tol=PTOL)
+ v = fp.e1((0.0 - 80.0j))
+ assert ae(v, (0.012402501155070958192 - 0.0015345601175906961199j), tol=ATOL)
+ assert ae(v.real, 0.012402501155070958192, tol=PTOL)
+ assert ae(v.imag, -0.0015345601175906961199, tol=PTOL)
+ v = fp.e1((1.1641532182693481445e-10 - 4.6566128730773925781e-10j))
+ assert ae(v, (20.880034621664969632 + 1.3258176632023711778j), tol=ATOL)
+ assert ae(v.real, 20.880034621664969632, tol=PTOL)
+ assert ae(v.imag, 1.3258176632023711778, tol=PTOL)
+ v = fp.e1((0.25 - 1.0j))
+ assert ae(v, (-0.16868306393667788761 + 0.4858011885947426971j), tol=ATOL)
+ assert ae(v.real, -0.16868306393667788761, tol=PTOL)
+ assert ae(v.imag, 0.4858011885947426971, tol=PTOL)
+ v = fp.e1((1.0 - 4.0j))
+ assert ae(v, (0.03373591813926547318 - 0.073523452241083821877j), tol=ATOL)
+ assert ae(v.real, 0.03373591813926547318, tol=PTOL)
+ assert ae(v.imag, -0.073523452241083821877, tol=PTOL)
+ v = fp.e1((2.0 - 8.0j))
+ assert ae(v, (-0.015392833434733785143 + 0.0031747121557605415914j), tol=ATOL)
+ assert ae(v.real, -0.015392833434733785143, tol=PTOL)
+ assert ae(v.imag, 0.0031747121557605415914, tol=PTOL)
+ v = fp.e1((5.0 - 20.0j))
+ assert ae(v, (-0.00024419662286542966525 + 0.00021008322966152755674j), tol=ATOL)
+ assert ae(v.real, -0.00024419662286542966525, tol=PTOL)
+ assert ae(v.imag, 0.00021008322966152755674, tol=PTOL)
+ v = fp.e1((20.0 - 80.0j))
+ assert ae(v, (2.3255552781051330088e-11 - 8.9463918891349438007e-12j), tol=ATOL)
+ assert ae(v.real, 2.3255552781051330088e-11, tol=PTOL)
+ assert ae(v.imag, -8.9463918891349438007e-12, tol=PTOL)
+ v = fp.e1((30.0 - 120.0j))
+ assert ae(v, (-2.7068919097124652332e-16 + 7.0477762411705130239e-16j), tol=ATOL)
+ assert ae(v.real, -2.7068919097124652332e-16, tol=PTOL)
+ assert ae(v.imag, 7.0477762411705130239e-16, tol=PTOL)
+ v = fp.e1((40.0 - 160.0j))
+ assert ae(v, (-1.1695597827678024687e-20 - 2.2907401455645736661e-20j), tol=ATOL)
+ assert ae(v.real, -1.1695597827678024687e-20, tol=PTOL)
+ assert ae(v.imag, -2.2907401455645736661e-20, tol=PTOL)
+ v = fp.e1((50.0 - 200.0j))
+ assert ae(v, (9.0323746914410162531e-25 + 2.3950601790033530935e-25j), tol=ATOL)
+ assert ae(v.real, 9.0323746914410162531e-25, tol=PTOL)
+ assert ae(v.imag, 2.3950601790033530935e-25, tol=PTOL)
+ v = fp.e1((80.0 - 320.0j))
+ assert ae(v, (3.4819106748728063576e-38 + 4.215653005615772724e-38j), tol=ATOL)
+ assert ae(v.real, 3.4819106748728063576e-38, tol=PTOL)
+ assert ae(v.imag, 4.215653005615772724e-38, tol=PTOL)
+ v = fp.e1((1.1641532182693481445e-10 - 1.1641532182693481445e-10j))
+ assert ae(v, (21.950067703413105017 + 0.7853981632810329878j), tol=ATOL)
+ assert ae(v.real, 21.950067703413105017, tol=PTOL)
+ assert ae(v.imag, 0.7853981632810329878, tol=PTOL)
+ v = fp.e1((0.25 - 0.25j))
+ assert ae(v, (0.71092525792923287894 + 0.56491812441304194711j), tol=ATOL)
+ assert ae(v.real, 0.71092525792923287894, tol=PTOL)
+ assert ae(v.imag, 0.56491812441304194711, tol=PTOL)
+ v = fp.e1((1.0 - 1.0j))
+ assert ae(v, (0.00028162445198141832551 + 0.17932453503935894015j), tol=ATOL)
+ assert ae(v.real, 0.00028162445198141832551, tol=PTOL)
+ assert ae(v.imag, 0.17932453503935894015, tol=PTOL)
+ v = fp.e1((2.0 - 2.0j))
+ assert ae(v, (-0.033767089606562004246 + 0.018599414169750541925j), tol=ATOL)
+ assert ae(v.real, -0.033767089606562004246, tol=PTOL)
+ assert ae(v.imag, 0.018599414169750541925, tol=PTOL)
+ v = fp.e1((5.0 - 5.0j))
+ assert ae(v, (0.0007266506660356393891 - 0.00047102780163522245054j), tol=ATOL)
+ assert ae(v.real, 0.0007266506660356393891, tol=PTOL)
+ assert ae(v.imag, -0.00047102780163522245054, tol=PTOL)
+ v = fp.e1((20.0 - 20.0j))
+ assert ae(v, (-2.3824537449367396579e-11 + 6.6969873156525615158e-11j), tol=ATOL)
+ assert ae(v.real, -2.3824537449367396579e-11, tol=PTOL)
+ assert ae(v.imag, 6.6969873156525615158e-11, tol=PTOL)
+ v = fp.e1((30.0 - 30.0j))
+ assert ae(v, (1.7316045841744061617e-15 - 1.3065678019487308689e-15j), tol=ATOL)
+ assert ae(v.real, 1.7316045841744061617e-15, tol=PTOL)
+ assert ae(v.imag, -1.3065678019487308689e-15, tol=PTOL)
+ v = fp.e1((40.0 - 40.0j))
+ assert ae(v, (-7.4001043002899232182e-20 + 4.991847855336816304e-21j), tol=ATOL)
+ assert ae(v.real, -7.4001043002899232182e-20, tol=PTOL)
+ assert ae(v.imag, 4.991847855336816304e-21, tol=PTOL)
+ v = fp.e1((50.0 - 50.0j))
+ assert ae(v, (2.3566128324644641219e-24 + 1.3188326726201614778e-24j), tol=ATOL)
+ assert ae(v.real, 2.3566128324644641219e-24, tol=PTOL)
+ assert ae(v.imag, 1.3188326726201614778e-24, tol=PTOL)
+ v = fp.e1((80.0 - 80.0j))
+ assert ae(v, (9.8279750572186526673e-38 - 1.243952841288868831e-37j), tol=ATOL)
+ assert ae(v.real, 9.8279750572186526673e-38, tol=PTOL)
+ assert ae(v.imag, -1.243952841288868831e-37, tol=PTOL)
+ v = fp.e1((4.6566128730773925781e-10 - 1.1641532182693481445e-10j))
+ assert ae(v, (20.880034622014215597 + 0.24497866301044883237j), tol=ATOL)
+ assert ae(v.real, 20.880034622014215597, tol=PTOL)
+ assert ae(v.imag, 0.24497866301044883237, tol=PTOL)
+ v = fp.e1((1.0 - 0.25j))
+ assert ae(v, (0.19731063945004229095 + 0.087366045774299963672j), tol=ATOL)
+ assert ae(v.real, 0.19731063945004229095, tol=PTOL)
+ assert ae(v.imag, 0.087366045774299963672, tol=PTOL)
+ v = fp.e1((4.0 - 1.0j))
+ assert ae(v, (0.0013106173980145506944 + 0.0034542480199350626699j), tol=ATOL)
+ assert ae(v.real, 0.0013106173980145506944, tol=PTOL)
+ assert ae(v.imag, 0.0034542480199350626699, tol=PTOL)
+ v = fp.e1((8.0 - 2.0j))
+ assert ae(v, (-0.000022278049065270225945 + 0.000029191940456521555288j), tol=ATOL)
+ assert ae(v.real, -0.000022278049065270225945, tol=PTOL)
+ assert ae(v.imag, 0.000029191940456521555288, tol=PTOL)
+ v = fp.e1((20.0 - 5.0j))
+ assert ae(v, (4.7711374515765346894e-11 - 8.2902652405126947359e-11j), tol=ATOL)
+ assert ae(v.real, 4.7711374515765346894e-11, tol=PTOL)
+ assert ae(v.imag, -8.2902652405126947359e-11, tol=PTOL)
+ v = fp.e1((80.0 - 20.0j))
+ assert ae(v, (3.8353473865788235787e-38 + 2.129247592349605139e-37j), tol=ATOL)
+ assert ae(v.real, 3.8353473865788235787e-38, tol=PTOL)
+ assert ae(v.imag, 2.129247592349605139e-37, tol=PTOL)
+ v = fp.e1((120.0 - 30.0j))
+ assert ae(v, (2.3836002337480334716e-55 - 5.6704043587126198306e-55j), tol=ATOL)
+ assert ae(v.real, 2.3836002337480334716e-55, tol=PTOL)
+ assert ae(v.imag, -5.6704043587126198306e-55, tol=PTOL)
+ v = fp.e1((160.0 - 40.0j))
+ assert ae(v, (-1.6238022898654510661e-72 + 1.104172355572287367e-72j), tol=ATOL)
+ assert ae(v.real, -1.6238022898654510661e-72, tol=PTOL)
+ assert ae(v.imag, 1.104172355572287367e-72, tol=PTOL)
+ v = fp.e1((200.0 - 50.0j))
+ assert ae(v, (6.6800061461666228487e-90 - 1.4473816083541016115e-91j), tol=ATOL)
+ assert ae(v.real, 6.6800061461666228487e-90, tol=PTOL)
+ assert ae(v.imag, -1.4473816083541016115e-91, tol=PTOL)
+ v = fp.e1((320.0 - 80.0j))
+ assert ae(v, (4.2737871527778786157e-143 - 3.1789935525785660314e-142j), tol=ATOL)
+ assert ae(v.real, 4.2737871527778786157e-143, tol=PTOL)
+ assert ae(v.imag, -3.1789935525785660314e-142, tol=PTOL)
+ v = fp.ei(1.1641532182693481445e-10)
+ assert ae(v, -22.296641293460247028, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(0.25)
+ assert ae(v, -0.54254326466191372953, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(1.0)
+ assert ae(v, 1.8951178163559367555, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(2.0)
+ assert ae(v, 4.9542343560018901634, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(5.0)
+ assert ae(v, 40.185275355803177455, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(20.0)
+ assert ae(v, 25615652.66405658882, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(30.0)
+ assert ae(v, 368973209407.27419706, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(40.0)
+ assert ae(v, 6039718263611241.5784, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(50.0)
+ assert ae(v, 1.0585636897131690963e+20, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(80.0)
+ assert ae(v, 7.0146000049047999696e+32, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei((1.1641532182693481445e-10 + 0.0j))
+ assert ae(v, (-22.296641293460247028 + 0.0j), tol=ATOL)
+ assert ae(v.real, -22.296641293460247028, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((0.25 + 0.0j))
+ assert ae(v, (-0.54254326466191372953 + 0.0j), tol=ATOL)
+ assert ae(v.real, -0.54254326466191372953, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((1.0 + 0.0j))
+ assert ae(v, (1.8951178163559367555 + 0.0j), tol=ATOL)
+ assert ae(v.real, 1.8951178163559367555, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((2.0 + 0.0j))
+ assert ae(v, (4.9542343560018901634 + 0.0j), tol=ATOL)
+ assert ae(v.real, 4.9542343560018901634, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((5.0 + 0.0j))
+ assert ae(v, (40.185275355803177455 + 0.0j), tol=ATOL)
+ assert ae(v.real, 40.185275355803177455, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((20.0 + 0.0j))
+ assert ae(v, (25615652.66405658882 + 0.0j), tol=ATOL)
+ assert ae(v.real, 25615652.66405658882, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((30.0 + 0.0j))
+ assert ae(v, (368973209407.27419706 + 0.0j), tol=ATOL)
+ assert ae(v.real, 368973209407.27419706, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((40.0 + 0.0j))
+ assert ae(v, (6039718263611241.5784 + 0.0j), tol=ATOL)
+ assert ae(v.real, 6039718263611241.5784, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((50.0 + 0.0j))
+ assert ae(v, (1.0585636897131690963e+20 + 0.0j), tol=ATOL)
+ assert ae(v.real, 1.0585636897131690963e+20, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((80.0 + 0.0j))
+ assert ae(v, (7.0146000049047999696e+32 + 0.0j), tol=ATOL)
+ assert ae(v.real, 7.0146000049047999696e+32, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((4.6566128730773925781e-10 + 1.1641532182693481445e-10j))
+ assert ae(v, (-20.880034621082893023 + 0.24497866324327947603j), tol=ATOL)
+ assert ae(v.real, -20.880034621082893023, tol=PTOL)
+ assert ae(v.imag, 0.24497866324327947603, tol=PTOL)
+ v = fp.ei((1.0 + 0.25j))
+ assert ae(v, (1.8942716983721074932 + 0.67268237088273915854j), tol=ATOL)
+ assert ae(v.real, 1.8942716983721074932, tol=PTOL)
+ assert ae(v.imag, 0.67268237088273915854, tol=PTOL)
+ v = fp.ei((4.0 + 1.0j))
+ assert ae(v, (14.806699492675420438 + 12.280015176673582616j), tol=ATOL)
+ assert ae(v.real, 14.806699492675420438, tol=PTOL)
+ assert ae(v.imag, 12.280015176673582616, tol=PTOL)
+ v = fp.ei((8.0 + 2.0j))
+ assert ae(v, (-54.633252667426386294 + 416.34477429173650012j), tol=ATOL)
+ assert ae(v.real, -54.633252667426386294, tol=PTOL)
+ assert ae(v.imag, 416.34477429173650012, tol=PTOL)
+ v = fp.ei((20.0 + 5.0j))
+ assert ae(v, (711836.97165402624643 - 24745247.798103247366j), tol=ATOL)
+ assert ae(v.real, 711836.97165402624643, tol=PTOL)
+ assert ae(v.imag, -24745247.798103247366, tol=PTOL)
+ v = fp.ei((80.0 + 20.0j))
+ assert ae(v, (4.2139911108612653091e+32 + 5.3367124741918251637e+32j), tol=ATOL)
+ assert ae(v.real, 4.2139911108612653091e+32, tol=PTOL)
+ assert ae(v.imag, 5.3367124741918251637e+32, tol=PTOL)
+ v = fp.ei((120.0 + 30.0j))
+ assert ae(v, (-9.7760616203707508892e+48 - 1.058257682317195792e+50j), tol=ATOL)
+ assert ae(v.real, -9.7760616203707508892e+48, tol=PTOL)
+ assert ae(v.imag, -1.058257682317195792e+50, tol=PTOL)
+ v = fp.ei((160.0 + 40.0j))
+ assert ae(v, (-8.7065541466623638861e+66 + 1.6577106725141739889e+67j), tol=ATOL)
+ assert ae(v.real, -8.7065541466623638861e+66, tol=PTOL)
+ assert ae(v.imag, 1.6577106725141739889e+67, tol=PTOL)
+ v = fp.ei((200.0 + 50.0j))
+ assert ae(v, (3.070744996327018106e+84 - 1.7243244846769415903e+84j), tol=ATOL)
+ assert ae(v.real, 3.070744996327018106e+84, tol=PTOL)
+ assert ae(v.imag, -1.7243244846769415903e+84, tol=PTOL)
+ v = fp.ei((320.0 + 80.0j))
+ assert ae(v, (-9.9960598637998647276e+135 - 2.6855081527595608863e+136j), tol=ATOL)
+ assert ae(v.real, -9.9960598637998647276e+135, tol=PTOL)
+ assert ae(v.imag, -2.6855081527595608863e+136, tol=PTOL)
+ v = fp.ei((1.1641532182693481445e-10 + 1.1641532182693481445e-10j))
+ assert ae(v, (-21.950067703180274374 + 0.78539816351386363145j), tol=ATOL)
+ assert ae(v.real, -21.950067703180274374, tol=PTOL)
+ assert ae(v.imag, 0.78539816351386363145, tol=PTOL)
+ v = fp.ei((0.25 + 0.25j))
+ assert ae(v, (-0.21441047326710323254 + 1.0683772981589995996j), tol=ATOL)
+ assert ae(v.real, -0.21441047326710323254, tol=PTOL)
+ assert ae(v.imag, 1.0683772981589995996, tol=PTOL)
+ v = fp.ei((1.0 + 1.0j))
+ assert ae(v, (1.7646259855638540684 + 2.3877698515105224193j), tol=ATOL)
+ assert ae(v.real, 1.7646259855638540684, tol=PTOL)
+ assert ae(v.imag, 2.3877698515105224193, tol=PTOL)
+ v = fp.ei((2.0 + 2.0j))
+ assert ae(v, (1.8920781621855474089 + 5.3169624378326579621j), tol=ATOL)
+ assert ae(v.real, 1.8920781621855474089, tol=PTOL)
+ assert ae(v.imag, 5.3169624378326579621, tol=PTOL)
+ v = fp.ei((5.0 + 5.0j))
+ assert ae(v, (-13.470936071475245856 - 15.322492395731230968j), tol=ATOL)
+ assert ae(v.real, -13.470936071475245856, tol=PTOL)
+ assert ae(v.imag, -15.322492395731230968, tol=PTOL)
+ v = fp.ei((20.0 + 20.0j))
+ assert ae(v, (16589317.398788971896 + 5831705.4712368307104j), tol=ATOL)
+ assert ae(v.real, 16589317.398788971896, tol=PTOL)
+ assert ae(v.imag, 5831705.4712368307104, tol=PTOL)
+ v = fp.ei((30.0 + 30.0j))
+ assert ae(v, (-154596484273.69322527 - 204179357834.2723043j), tol=ATOL)
+ assert ae(v.real, -154596484273.69322527, tol=PTOL)
+ assert ae(v.imag, -204179357834.2723043, tol=PTOL)
+ v = fp.ei((40.0 + 40.0j))
+ assert ae(v, (287512180321448.45408 + 4203502407932318.1156j), tol=ATOL)
+ assert ae(v.real, 287512180321448.45408, tol=PTOL)
+ assert ae(v.imag, 4203502407932318.1156, tol=PTOL)
+ v = fp.ei((50.0 + 50.0j))
+ assert ae(v, (36128528616649268826.0 - 64648801861338741960.0j), tol=ATOL)
+ assert ae(v.real, 36128528616649268826.0, tol=PTOL)
+ assert ae(v.imag, -64648801861338741960.0, tol=PTOL)
+ v = fp.ei((80.0 + 80.0j))
+ assert ae(v, (-3.8674816337930010217e+32 - 3.0540709639658071041e+32j), tol=ATOL)
+ assert ae(v.real, -3.8674816337930010217e+32, tol=PTOL)
+ assert ae(v.imag, -3.0540709639658071041e+32, tol=PTOL)
+ v = fp.ei((1.1641532182693481445e-10 + 4.6566128730773925781e-10j))
+ assert ae(v, (-20.880034621432138988 + 1.3258176641336937524j), tol=ATOL)
+ assert ae(v.real, -20.880034621432138988, tol=PTOL)
+ assert ae(v.imag, 1.3258176641336937524, tol=PTOL)
+ v = fp.ei((0.25 + 1.0j))
+ assert ae(v, (0.59066621214766308594 + 2.3968481059377428687j), tol=ATOL)
+ assert ae(v.real, 0.59066621214766308594, tol=PTOL)
+ assert ae(v.imag, 2.3968481059377428687, tol=PTOL)
+ v = fp.ei((1.0 + 4.0j))
+ assert ae(v, (-0.49739047283060471093 + 3.5570287076301818702j), tol=ATOL)
+ assert ae(v.real, -0.49739047283060471093, tol=PTOL)
+ assert ae(v.imag, 3.5570287076301818702, tol=PTOL)
+ v = fp.ei((2.0 + 8.0j))
+ assert ae(v, (0.8705211147733730969 + 3.3825859385758486351j), tol=ATOL)
+ assert ae(v.real, 0.8705211147733730969, tol=PTOL)
+ assert ae(v.imag, 3.3825859385758486351, tol=PTOL)
+ v = fp.ei((5.0 + 20.0j))
+ assert ae(v, (7.0789514293925893007 + 1.5313749363937141849j), tol=ATOL)
+ assert ae(v.real, 7.0789514293925893007, tol=PTOL)
+ assert ae(v.imag, 1.5313749363937141849, tol=PTOL)
+ v = fp.ei((20.0 + 80.0j))
+ assert ae(v, (-5855431.4907298084434 - 720917.79156143806727j), tol=ATOL)
+ assert ae(v.real, -5855431.4907298084434, tol=PTOL)
+ assert ae(v.imag, -720917.79156143806727, tol=PTOL)
+ v = fp.ei((30.0 + 120.0j))
+ assert ae(v, (65402491644.703470747 - 56697658396.51586764j), tol=ATOL)
+ assert ae(v.real, 65402491644.703470747, tol=PTOL)
+ assert ae(v.imag, -56697658396.51586764, tol=PTOL)
+ v = fp.ei((40.0 + 160.0j))
+ assert ae(v, (-25504929379604.776769 + 1429035198630576.3879j), tol=ATOL)
+ assert ae(v.real, -25504929379604.776769, tol=PTOL)
+ assert ae(v.imag, 1429035198630576.3879, tol=PTOL)
+ v = fp.ei((50.0 + 200.0j))
+ assert ae(v, (-18437746526988116954.0 - 17146362239046152342.0j), tol=ATOL)
+ assert ae(v.real, -18437746526988116954.0, tol=PTOL)
+ assert ae(v.imag, -17146362239046152342.0, tol=PTOL)
+ v = fp.ei((80.0 + 320.0j))
+ assert ae(v, (-3.3464697299634526706e+31 - 1.6473152633843023919e+32j), tol=ATOL)
+ assert ae(v.real, -3.3464697299634526706e+31, tol=PTOL)
+ assert ae(v.imag, -1.6473152633843023919e+32, tol=PTOL)
+ v = fp.ei((0.0 + 1.1641532182693481445e-10j))
+ assert ae(v, (-22.29664129357666235 + 1.5707963269113119411j), tol=ATOL)
+ assert ae(v.real, -22.29664129357666235, tol=PTOL)
+ assert ae(v.imag, 1.5707963269113119411, tol=PTOL)
+ v = fp.ei((0.0 + 0.25j))
+ assert ae(v, (-0.82466306258094565309 + 1.8199298971146537833j), tol=ATOL)
+ assert ae(v.real, -0.82466306258094565309, tol=PTOL)
+ assert ae(v.imag, 1.8199298971146537833, tol=PTOL)
+ v = fp.ei((0.0 + 1.0j))
+ assert ae(v, (0.33740392290096813466 + 2.5168793971620796342j), tol=ATOL)
+ assert ae(v.real, 0.33740392290096813466, tol=PTOL)
+ assert ae(v.imag, 2.5168793971620796342, tol=PTOL)
+ v = fp.ei((0.0 + 2.0j))
+ assert ae(v, (0.4229808287748649957 + 3.1762093035975914678j), tol=ATOL)
+ assert ae(v.real, 0.4229808287748649957, tol=PTOL)
+ assert ae(v.imag, 3.1762093035975914678, tol=PTOL)
+ v = fp.ei((0.0 + 5.0j))
+ assert ae(v, (-0.19002974965664387862 + 3.1207275717395707565j), tol=ATOL)
+ assert ae(v.real, -0.19002974965664387862, tol=PTOL)
+ assert ae(v.imag, 3.1207275717395707565, tol=PTOL)
+ v = fp.ei((0.0 + 20.0j))
+ assert ae(v, (0.04441982084535331654 + 3.1190380278383364594j), tol=ATOL)
+ assert ae(v.real, 0.04441982084535331654, tol=PTOL)
+ assert ae(v.imag, 3.1190380278383364594, tol=PTOL)
+ v = fp.ei((0.0 + 30.0j))
+ assert ae(v, (-0.033032417282071143779 + 3.1375528668252477302j), tol=ATOL)
+ assert ae(v.real, -0.033032417282071143779, tol=PTOL)
+ assert ae(v.imag, 3.1375528668252477302, tol=PTOL)
+ v = fp.ei((0.0 + 40.0j))
+ assert ae(v, (0.019020007896208766962 + 3.157781446149681126j), tol=ATOL)
+ assert ae(v.real, 0.019020007896208766962, tol=PTOL)
+ assert ae(v.imag, 3.157781446149681126, tol=PTOL)
+ v = fp.ei((0.0 + 50.0j))
+ assert ae(v, (-0.0056283863241163054402 + 3.122413399280832514j), tol=ATOL)
+ assert ae(v.real, -0.0056283863241163054402, tol=PTOL)
+ assert ae(v.imag, 3.122413399280832514, tol=PTOL)
+ v = fp.ei((0.0 + 80.0j))
+ assert ae(v, (-0.012402501155070958192 + 3.1431272137073839346j), tol=ATOL)
+ assert ae(v.real, -0.012402501155070958192, tol=PTOL)
+ assert ae(v.imag, 3.1431272137073839346, tol=PTOL)
+ v = fp.ei((-1.1641532182693481445e-10 + 4.6566128730773925781e-10j))
+ assert ae(v, (-20.880034621664969632 + 1.8157749903874220607j), tol=ATOL)
+ assert ae(v.real, -20.880034621664969632, tol=PTOL)
+ assert ae(v.imag, 1.8157749903874220607, tol=PTOL)
+ v = fp.ei((-0.25 + 1.0j))
+ assert ae(v, (0.16868306393667788761 + 2.6557914649950505414j), tol=ATOL)
+ assert ae(v.real, 0.16868306393667788761, tol=PTOL)
+ assert ae(v.imag, 2.6557914649950505414, tol=PTOL)
+ v = fp.ei((-1.0 + 4.0j))
+ assert ae(v, (-0.03373591813926547318 + 3.2151161058308770603j), tol=ATOL)
+ assert ae(v.real, -0.03373591813926547318, tol=PTOL)
+ assert ae(v.imag, 3.2151161058308770603, tol=PTOL)
+ v = fp.ei((-2.0 + 8.0j))
+ assert ae(v, (0.015392833434733785143 + 3.1384179414340326969j), tol=ATOL)
+ assert ae(v.real, 0.015392833434733785143, tol=PTOL)
+ assert ae(v.imag, 3.1384179414340326969, tol=PTOL)
+ v = fp.ei((-5.0 + 20.0j))
+ assert ae(v, (0.00024419662286542966525 + 3.1413825703601317109j), tol=ATOL)
+ assert ae(v.real, 0.00024419662286542966525, tol=PTOL)
+ assert ae(v.imag, 3.1413825703601317109, tol=PTOL)
+ v = fp.ei((-20.0 + 80.0j))
+ assert ae(v, (-2.3255552781051330088e-11 + 3.1415926535987396304j), tol=ATOL)
+ assert ae(v.real, -2.3255552781051330088e-11, tol=PTOL)
+ assert ae(v.imag, 3.1415926535987396304, tol=PTOL)
+ v = fp.ei((-30.0 + 120.0j))
+ assert ae(v, (2.7068919097124652332e-16 + 3.1415926535897925337j), tol=ATOL)
+ assert ae(v.real, 2.7068919097124652332e-16, tol=PTOL)
+ assert ae(v.imag, 3.1415926535897925337, tol=PTOL)
+ v = fp.ei((-40.0 + 160.0j))
+ assert ae(v, (1.1695597827678024687e-20 + 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, 1.1695597827678024687e-20, tol=PTOL)
+ assert ae(v.imag, 3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-50.0 + 200.0j))
+ assert ae(v, (-9.0323746914410162531e-25 + 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -9.0323746914410162531e-25, tol=PTOL)
+ assert ae(v.imag, 3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-80.0 + 320.0j))
+ assert ae(v, (-3.4819106748728063576e-38 + 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -3.4819106748728063576e-38, tol=PTOL)
+ assert ae(v.imag, 3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-4.6566128730773925781e-10 + 1.1641532182693481445e-10j))
+ assert ae(v, (-20.880034622014215597 + 2.8966139905793444061j), tol=ATOL)
+ assert ae(v.real, -20.880034622014215597, tol=PTOL)
+ assert ae(v.imag, 2.8966139905793444061, tol=PTOL)
+ v = fp.ei((-1.0 + 0.25j))
+ assert ae(v, (-0.19731063945004229095 + 3.0542266078154932748j), tol=ATOL)
+ assert ae(v.real, -0.19731063945004229095, tol=PTOL)
+ assert ae(v.imag, 3.0542266078154932748, tol=PTOL)
+ v = fp.ei((-4.0 + 1.0j))
+ assert ae(v, (-0.0013106173980145506944 + 3.1381384055698581758j), tol=ATOL)
+ assert ae(v.real, -0.0013106173980145506944, tol=PTOL)
+ assert ae(v.imag, 3.1381384055698581758, tol=PTOL)
+ v = fp.ei((-8.0 + 2.0j))
+ assert ae(v, (0.000022278049065270225945 + 3.1415634616493367169j), tol=ATOL)
+ assert ae(v.real, 0.000022278049065270225945, tol=PTOL)
+ assert ae(v.imag, 3.1415634616493367169, tol=PTOL)
+ v = fp.ei((-20.0 + 5.0j))
+ assert ae(v, (-4.7711374515765346894e-11 + 3.1415926536726958909j), tol=ATOL)
+ assert ae(v.real, -4.7711374515765346894e-11, tol=PTOL)
+ assert ae(v.imag, 3.1415926536726958909, tol=PTOL)
+ v = fp.ei((-80.0 + 20.0j))
+ assert ae(v, (-3.8353473865788235787e-38 + 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -3.8353473865788235787e-38, tol=PTOL)
+ assert ae(v.imag, 3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-120.0 + 30.0j))
+ assert ae(v, (-2.3836002337480334716e-55 + 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -2.3836002337480334716e-55, tol=PTOL)
+ assert ae(v.imag, 3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-160.0 + 40.0j))
+ assert ae(v, (1.6238022898654510661e-72 + 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, 1.6238022898654510661e-72, tol=PTOL)
+ assert ae(v.imag, 3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-200.0 + 50.0j))
+ assert ae(v, (-6.6800061461666228487e-90 + 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -6.6800061461666228487e-90, tol=PTOL)
+ assert ae(v.imag, 3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-320.0 + 80.0j))
+ assert ae(v, (-4.2737871527778786157e-143 + 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -4.2737871527778786157e-143, tol=PTOL)
+ assert ae(v.imag, 3.1415926535897932385, tol=PTOL)
+ v = fp.ei(-1.1641532182693481445e-10)
+ assert ae(v, -22.296641293693077672, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(-0.25)
+ assert ae(v, -1.0442826344437381945, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(-1.0)
+ assert ae(v, -0.21938393439552027368, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(-2.0)
+ assert ae(v, -0.048900510708061119567, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(-5.0)
+ assert ae(v, -0.0011482955912753257973, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(-20.0)
+ assert ae(v, -9.8355252906498816904e-11, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(-30.0)
+ assert ae(v, -3.0215520106888125448e-15, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(-40.0)
+ assert ae(v, -1.0367732614516569722e-19, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(-50.0)
+ assert ae(v, -3.7832640295504590187e-24, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei(-80.0)
+ assert ae(v, -2.2285432586884729112e-37, tol=ATOL)
+ assert type(v) is float
+ v = fp.ei((-1.1641532182693481445e-10 + 0.0j))
+ assert ae(v, (-22.296641293693077672 + 0.0j), tol=ATOL)
+ assert ae(v.real, -22.296641293693077672, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((-0.25 + 0.0j))
+ assert ae(v, (-1.0442826344437381945 + 0.0j), tol=ATOL)
+ assert ae(v.real, -1.0442826344437381945, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((-1.0 + 0.0j))
+ assert ae(v, (-0.21938393439552027368 + 0.0j), tol=ATOL)
+ assert ae(v.real, -0.21938393439552027368, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((-2.0 + 0.0j))
+ assert ae(v, (-0.048900510708061119567 + 0.0j), tol=ATOL)
+ assert ae(v.real, -0.048900510708061119567, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((-5.0 + 0.0j))
+ assert ae(v, (-0.0011482955912753257973 + 0.0j), tol=ATOL)
+ assert ae(v.real, -0.0011482955912753257973, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((-20.0 + 0.0j))
+ assert ae(v, (-9.8355252906498816904e-11 + 0.0j), tol=ATOL)
+ assert ae(v.real, -9.8355252906498816904e-11, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((-30.0 + 0.0j))
+ assert ae(v, (-3.0215520106888125448e-15 + 0.0j), tol=ATOL)
+ assert ae(v.real, -3.0215520106888125448e-15, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((-40.0 + 0.0j))
+ assert ae(v, (-1.0367732614516569722e-19 + 0.0j), tol=ATOL)
+ assert ae(v.real, -1.0367732614516569722e-19, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((-50.0 + 0.0j))
+ assert ae(v, (-3.7832640295504590187e-24 + 0.0j), tol=ATOL)
+ assert ae(v.real, -3.7832640295504590187e-24, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((-80.0 + 0.0j))
+ assert ae(v, (-2.2285432586884729112e-37 + 0.0j), tol=ATOL)
+ assert ae(v.real, -2.2285432586884729112e-37, tol=PTOL)
+ assert v.imag == 0
+ v = fp.ei((-4.6566128730773925781e-10 - 1.1641532182693481445e-10j))
+ assert ae(v, (-20.880034622014215597 - 2.8966139905793444061j), tol=ATOL)
+ assert ae(v.real, -20.880034622014215597, tol=PTOL)
+ assert ae(v.imag, -2.8966139905793444061, tol=PTOL)
+ v = fp.ei((-1.0 - 0.25j))
+ assert ae(v, (-0.19731063945004229095 - 3.0542266078154932748j), tol=ATOL)
+ assert ae(v.real, -0.19731063945004229095, tol=PTOL)
+ assert ae(v.imag, -3.0542266078154932748, tol=PTOL)
+ v = fp.ei((-4.0 - 1.0j))
+ assert ae(v, (-0.0013106173980145506944 - 3.1381384055698581758j), tol=ATOL)
+ assert ae(v.real, -0.0013106173980145506944, tol=PTOL)
+ assert ae(v.imag, -3.1381384055698581758, tol=PTOL)
+ v = fp.ei((-8.0 - 2.0j))
+ assert ae(v, (0.000022278049065270225945 - 3.1415634616493367169j), tol=ATOL)
+ assert ae(v.real, 0.000022278049065270225945, tol=PTOL)
+ assert ae(v.imag, -3.1415634616493367169, tol=PTOL)
+ v = fp.ei((-20.0 - 5.0j))
+ assert ae(v, (-4.7711374515765346894e-11 - 3.1415926536726958909j), tol=ATOL)
+ assert ae(v.real, -4.7711374515765346894e-11, tol=PTOL)
+ assert ae(v.imag, -3.1415926536726958909, tol=PTOL)
+ v = fp.ei((-80.0 - 20.0j))
+ assert ae(v, (-3.8353473865788235787e-38 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -3.8353473865788235787e-38, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-120.0 - 30.0j))
+ assert ae(v, (-2.3836002337480334716e-55 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -2.3836002337480334716e-55, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-160.0 - 40.0j))
+ assert ae(v, (1.6238022898654510661e-72 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, 1.6238022898654510661e-72, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-200.0 - 50.0j))
+ assert ae(v, (-6.6800061461666228487e-90 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -6.6800061461666228487e-90, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-320.0 - 80.0j))
+ assert ae(v, (-4.2737871527778786157e-143 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -4.2737871527778786157e-143, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-1.1641532182693481445e-10 - 1.1641532182693481445e-10j))
+ assert ae(v, (-21.950067703413105017 - 2.3561944903087602507j), tol=ATOL)
+ assert ae(v.real, -21.950067703413105017, tol=PTOL)
+ assert ae(v.imag, -2.3561944903087602507, tol=PTOL)
+ v = fp.ei((-0.25 - 0.25j))
+ assert ae(v, (-0.71092525792923287894 - 2.5766745291767512913j), tol=ATOL)
+ assert ae(v.real, -0.71092525792923287894, tol=PTOL)
+ assert ae(v.imag, -2.5766745291767512913, tol=PTOL)
+ v = fp.ei((-1.0 - 1.0j))
+ assert ae(v, (-0.00028162445198141832551 - 2.9622681185504342983j), tol=ATOL)
+ assert ae(v.real, -0.00028162445198141832551, tol=PTOL)
+ assert ae(v.imag, -2.9622681185504342983, tol=PTOL)
+ v = fp.ei((-2.0 - 2.0j))
+ assert ae(v, (0.033767089606562004246 - 3.1229932394200426965j), tol=ATOL)
+ assert ae(v.real, 0.033767089606562004246, tol=PTOL)
+ assert ae(v.imag, -3.1229932394200426965, tol=PTOL)
+ v = fp.ei((-5.0 - 5.0j))
+ assert ae(v, (-0.0007266506660356393891 - 3.1420636813914284609j), tol=ATOL)
+ assert ae(v.real, -0.0007266506660356393891, tol=PTOL)
+ assert ae(v.imag, -3.1420636813914284609, tol=PTOL)
+ v = fp.ei((-20.0 - 20.0j))
+ assert ae(v, (2.3824537449367396579e-11 - 3.1415926535228233653j), tol=ATOL)
+ assert ae(v.real, 2.3824537449367396579e-11, tol=PTOL)
+ assert ae(v.imag, -3.1415926535228233653, tol=PTOL)
+ v = fp.ei((-30.0 - 30.0j))
+ assert ae(v, (-1.7316045841744061617e-15 - 3.141592653589794545j), tol=ATOL)
+ assert ae(v.real, -1.7316045841744061617e-15, tol=PTOL)
+ assert ae(v.imag, -3.141592653589794545, tol=PTOL)
+ v = fp.ei((-40.0 - 40.0j))
+ assert ae(v, (7.4001043002899232182e-20 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, 7.4001043002899232182e-20, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-50.0 - 50.0j))
+ assert ae(v, (-2.3566128324644641219e-24 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -2.3566128324644641219e-24, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-80.0 - 80.0j))
+ assert ae(v, (-9.8279750572186526673e-38 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -9.8279750572186526673e-38, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-1.1641532182693481445e-10 - 4.6566128730773925781e-10j))
+ assert ae(v, (-20.880034621664969632 - 1.8157749903874220607j), tol=ATOL)
+ assert ae(v.real, -20.880034621664969632, tol=PTOL)
+ assert ae(v.imag, -1.8157749903874220607, tol=PTOL)
+ v = fp.ei((-0.25 - 1.0j))
+ assert ae(v, (0.16868306393667788761 - 2.6557914649950505414j), tol=ATOL)
+ assert ae(v.real, 0.16868306393667788761, tol=PTOL)
+ assert ae(v.imag, -2.6557914649950505414, tol=PTOL)
+ v = fp.ei((-1.0 - 4.0j))
+ assert ae(v, (-0.03373591813926547318 - 3.2151161058308770603j), tol=ATOL)
+ assert ae(v.real, -0.03373591813926547318, tol=PTOL)
+ assert ae(v.imag, -3.2151161058308770603, tol=PTOL)
+ v = fp.ei((-2.0 - 8.0j))
+ assert ae(v, (0.015392833434733785143 - 3.1384179414340326969j), tol=ATOL)
+ assert ae(v.real, 0.015392833434733785143, tol=PTOL)
+ assert ae(v.imag, -3.1384179414340326969, tol=PTOL)
+ v = fp.ei((-5.0 - 20.0j))
+ assert ae(v, (0.00024419662286542966525 - 3.1413825703601317109j), tol=ATOL)
+ assert ae(v.real, 0.00024419662286542966525, tol=PTOL)
+ assert ae(v.imag, -3.1413825703601317109, tol=PTOL)
+ v = fp.ei((-20.0 - 80.0j))
+ assert ae(v, (-2.3255552781051330088e-11 - 3.1415926535987396304j), tol=ATOL)
+ assert ae(v.real, -2.3255552781051330088e-11, tol=PTOL)
+ assert ae(v.imag, -3.1415926535987396304, tol=PTOL)
+ v = fp.ei((-30.0 - 120.0j))
+ assert ae(v, (2.7068919097124652332e-16 - 3.1415926535897925337j), tol=ATOL)
+ assert ae(v.real, 2.7068919097124652332e-16, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897925337, tol=PTOL)
+ v = fp.ei((-40.0 - 160.0j))
+ assert ae(v, (1.1695597827678024687e-20 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, 1.1695597827678024687e-20, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-50.0 - 200.0j))
+ assert ae(v, (-9.0323746914410162531e-25 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -9.0323746914410162531e-25, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.ei((-80.0 - 320.0j))
+ assert ae(v, (-3.4819106748728063576e-38 - 3.1415926535897932385j), tol=ATOL)
+ assert ae(v.real, -3.4819106748728063576e-38, tol=PTOL)
+ assert ae(v.imag, -3.1415926535897932385, tol=PTOL)
+ v = fp.ei((0.0 - 1.1641532182693481445e-10j))
+ assert ae(v, (-22.29664129357666235 - 1.5707963269113119411j), tol=ATOL)
+ assert ae(v.real, -22.29664129357666235, tol=PTOL)
+ assert ae(v.imag, -1.5707963269113119411, tol=PTOL)
+ v = fp.ei((0.0 - 0.25j))
+ assert ae(v, (-0.82466306258094565309 - 1.8199298971146537833j), tol=ATOL)
+ assert ae(v.real, -0.82466306258094565309, tol=PTOL)
+ assert ae(v.imag, -1.8199298971146537833, tol=PTOL)
+ v = fp.ei((0.0 - 1.0j))
+ assert ae(v, (0.33740392290096813466 - 2.5168793971620796342j), tol=ATOL)
+ assert ae(v.real, 0.33740392290096813466, tol=PTOL)
+ assert ae(v.imag, -2.5168793971620796342, tol=PTOL)
+ v = fp.ei((0.0 - 2.0j))
+ assert ae(v, (0.4229808287748649957 - 3.1762093035975914678j), tol=ATOL)
+ assert ae(v.real, 0.4229808287748649957, tol=PTOL)
+ assert ae(v.imag, -3.1762093035975914678, tol=PTOL)
+ v = fp.ei((0.0 - 5.0j))
+ assert ae(v, (-0.19002974965664387862 - 3.1207275717395707565j), tol=ATOL)
+ assert ae(v.real, -0.19002974965664387862, tol=PTOL)
+ assert ae(v.imag, -3.1207275717395707565, tol=PTOL)
+ v = fp.ei((0.0 - 20.0j))
+ assert ae(v, (0.04441982084535331654 - 3.1190380278383364594j), tol=ATOL)
+ assert ae(v.real, 0.04441982084535331654, tol=PTOL)
+ assert ae(v.imag, -3.1190380278383364594, tol=PTOL)
+ v = fp.ei((0.0 - 30.0j))
+ assert ae(v, (-0.033032417282071143779 - 3.1375528668252477302j), tol=ATOL)
+ assert ae(v.real, -0.033032417282071143779, tol=PTOL)
+ assert ae(v.imag, -3.1375528668252477302, tol=PTOL)
+ v = fp.ei((0.0 - 40.0j))
+ assert ae(v, (0.019020007896208766962 - 3.157781446149681126j), tol=ATOL)
+ assert ae(v.real, 0.019020007896208766962, tol=PTOL)
+ assert ae(v.imag, -3.157781446149681126, tol=PTOL)
+ v = fp.ei((0.0 - 50.0j))
+ assert ae(v, (-0.0056283863241163054402 - 3.122413399280832514j), tol=ATOL)
+ assert ae(v.real, -0.0056283863241163054402, tol=PTOL)
+ assert ae(v.imag, -3.122413399280832514, tol=PTOL)
+ v = fp.ei((0.0 - 80.0j))
+ assert ae(v, (-0.012402501155070958192 - 3.1431272137073839346j), tol=ATOL)
+ assert ae(v.real, -0.012402501155070958192, tol=PTOL)
+ assert ae(v.imag, -3.1431272137073839346, tol=PTOL)
+ v = fp.ei((1.1641532182693481445e-10 - 4.6566128730773925781e-10j))
+ assert ae(v, (-20.880034621432138988 - 1.3258176641336937524j), tol=ATOL)
+ assert ae(v.real, -20.880034621432138988, tol=PTOL)
+ assert ae(v.imag, -1.3258176641336937524, tol=PTOL)
+ v = fp.ei((0.25 - 1.0j))
+ assert ae(v, (0.59066621214766308594 - 2.3968481059377428687j), tol=ATOL)
+ assert ae(v.real, 0.59066621214766308594, tol=PTOL)
+ assert ae(v.imag, -2.3968481059377428687, tol=PTOL)
+ v = fp.ei((1.0 - 4.0j))
+ assert ae(v, (-0.49739047283060471093 - 3.5570287076301818702j), tol=ATOL)
+ assert ae(v.real, -0.49739047283060471093, tol=PTOL)
+ assert ae(v.imag, -3.5570287076301818702, tol=PTOL)
+ v = fp.ei((2.0 - 8.0j))
+ assert ae(v, (0.8705211147733730969 - 3.3825859385758486351j), tol=ATOL)
+ assert ae(v.real, 0.8705211147733730969, tol=PTOL)
+ assert ae(v.imag, -3.3825859385758486351, tol=PTOL)
+ v = fp.ei((5.0 - 20.0j))
+ assert ae(v, (7.0789514293925893007 - 1.5313749363937141849j), tol=ATOL)
+ assert ae(v.real, 7.0789514293925893007, tol=PTOL)
+ assert ae(v.imag, -1.5313749363937141849, tol=PTOL)
+ v = fp.ei((20.0 - 80.0j))
+ assert ae(v, (-5855431.4907298084434 + 720917.79156143806727j), tol=ATOL)
+ assert ae(v.real, -5855431.4907298084434, tol=PTOL)
+ assert ae(v.imag, 720917.79156143806727, tol=PTOL)
+ v = fp.ei((30.0 - 120.0j))
+ assert ae(v, (65402491644.703470747 + 56697658396.51586764j), tol=ATOL)
+ assert ae(v.real, 65402491644.703470747, tol=PTOL)
+ assert ae(v.imag, 56697658396.51586764, tol=PTOL)
+ v = fp.ei((40.0 - 160.0j))
+ assert ae(v, (-25504929379604.776769 - 1429035198630576.3879j), tol=ATOL)
+ assert ae(v.real, -25504929379604.776769, tol=PTOL)
+ assert ae(v.imag, -1429035198630576.3879, tol=PTOL)
+ v = fp.ei((50.0 - 200.0j))
+ assert ae(v, (-18437746526988116954.0 + 17146362239046152342.0j), tol=ATOL)
+ assert ae(v.real, -18437746526988116954.0, tol=PTOL)
+ assert ae(v.imag, 17146362239046152342.0, tol=PTOL)
+ v = fp.ei((80.0 - 320.0j))
+ assert ae(v, (-3.3464697299634526706e+31 + 1.6473152633843023919e+32j), tol=ATOL)
+ assert ae(v.real, -3.3464697299634526706e+31, tol=PTOL)
+ assert ae(v.imag, 1.6473152633843023919e+32, tol=PTOL)
+ v = fp.ei((1.1641532182693481445e-10 - 1.1641532182693481445e-10j))
+ assert ae(v, (-21.950067703180274374 - 0.78539816351386363145j), tol=ATOL)
+ assert ae(v.real, -21.950067703180274374, tol=PTOL)
+ assert ae(v.imag, -0.78539816351386363145, tol=PTOL)
+ v = fp.ei((0.25 - 0.25j))
+ assert ae(v, (-0.21441047326710323254 - 1.0683772981589995996j), tol=ATOL)
+ assert ae(v.real, -0.21441047326710323254, tol=PTOL)
+ assert ae(v.imag, -1.0683772981589995996, tol=PTOL)
+ v = fp.ei((1.0 - 1.0j))
+ assert ae(v, (1.7646259855638540684 - 2.3877698515105224193j), tol=ATOL)
+ assert ae(v.real, 1.7646259855638540684, tol=PTOL)
+ assert ae(v.imag, -2.3877698515105224193, tol=PTOL)
+ v = fp.ei((2.0 - 2.0j))
+ assert ae(v, (1.8920781621855474089 - 5.3169624378326579621j), tol=ATOL)
+ assert ae(v.real, 1.8920781621855474089, tol=PTOL)
+ assert ae(v.imag, -5.3169624378326579621, tol=PTOL)
+ v = fp.ei((5.0 - 5.0j))
+ assert ae(v, (-13.470936071475245856 + 15.322492395731230968j), tol=ATOL)
+ assert ae(v.real, -13.470936071475245856, tol=PTOL)
+ assert ae(v.imag, 15.322492395731230968, tol=PTOL)
+ v = fp.ei((20.0 - 20.0j))
+ assert ae(v, (16589317.398788971896 - 5831705.4712368307104j), tol=ATOL)
+ assert ae(v.real, 16589317.398788971896, tol=PTOL)
+ assert ae(v.imag, -5831705.4712368307104, tol=PTOL)
+ v = fp.ei((30.0 - 30.0j))
+ assert ae(v, (-154596484273.69322527 + 204179357834.2723043j), tol=ATOL)
+ assert ae(v.real, -154596484273.69322527, tol=PTOL)
+ assert ae(v.imag, 204179357834.2723043, tol=PTOL)
+ v = fp.ei((40.0 - 40.0j))
+ assert ae(v, (287512180321448.45408 - 4203502407932318.1156j), tol=ATOL)
+ assert ae(v.real, 287512180321448.45408, tol=PTOL)
+ assert ae(v.imag, -4203502407932318.1156, tol=PTOL)
+ v = fp.ei((50.0 - 50.0j))
+ assert ae(v, (36128528616649268826.0 + 64648801861338741960.0j), tol=ATOL)
+ assert ae(v.real, 36128528616649268826.0, tol=PTOL)
+ assert ae(v.imag, 64648801861338741960.0, tol=PTOL)
+ v = fp.ei((80.0 - 80.0j))
+ assert ae(v, (-3.8674816337930010217e+32 + 3.0540709639658071041e+32j), tol=ATOL)
+ assert ae(v.real, -3.8674816337930010217e+32, tol=PTOL)
+ assert ae(v.imag, 3.0540709639658071041e+32, tol=PTOL)
+ v = fp.ei((4.6566128730773925781e-10 - 1.1641532182693481445e-10j))
+ assert ae(v, (-20.880034621082893023 - 0.24497866324327947603j), tol=ATOL)
+ assert ae(v.real, -20.880034621082893023, tol=PTOL)
+ assert ae(v.imag, -0.24497866324327947603, tol=PTOL)
+ v = fp.ei((1.0 - 0.25j))
+ assert ae(v, (1.8942716983721074932 - 0.67268237088273915854j), tol=ATOL)
+ assert ae(v.real, 1.8942716983721074932, tol=PTOL)
+ assert ae(v.imag, -0.67268237088273915854, tol=PTOL)
+ v = fp.ei((4.0 - 1.0j))
+ assert ae(v, (14.806699492675420438 - 12.280015176673582616j), tol=ATOL)
+ assert ae(v.real, 14.806699492675420438, tol=PTOL)
+ assert ae(v.imag, -12.280015176673582616, tol=PTOL)
+ v = fp.ei((8.0 - 2.0j))
+ assert ae(v, (-54.633252667426386294 - 416.34477429173650012j), tol=ATOL)
+ assert ae(v.real, -54.633252667426386294, tol=PTOL)
+ assert ae(v.imag, -416.34477429173650012, tol=PTOL)
+ v = fp.ei((20.0 - 5.0j))
+ assert ae(v, (711836.97165402624643 + 24745247.798103247366j), tol=ATOL)
+ assert ae(v.real, 711836.97165402624643, tol=PTOL)
+ assert ae(v.imag, 24745247.798103247366, tol=PTOL)
+ v = fp.ei((80.0 - 20.0j))
+ assert ae(v, (4.2139911108612653091e+32 - 5.3367124741918251637e+32j), tol=ATOL)
+ assert ae(v.real, 4.2139911108612653091e+32, tol=PTOL)
+ assert ae(v.imag, -5.3367124741918251637e+32, tol=PTOL)
+ v = fp.ei((120.0 - 30.0j))
+ assert ae(v, (-9.7760616203707508892e+48 + 1.058257682317195792e+50j), tol=ATOL)
+ assert ae(v.real, -9.7760616203707508892e+48, tol=PTOL)
+ assert ae(v.imag, 1.058257682317195792e+50, tol=PTOL)
+ v = fp.ei((160.0 - 40.0j))
+ assert ae(v, (-8.7065541466623638861e+66 - 1.6577106725141739889e+67j), tol=ATOL)
+ assert ae(v.real, -8.7065541466623638861e+66, tol=PTOL)
+ assert ae(v.imag, -1.6577106725141739889e+67, tol=PTOL)
+ v = fp.ei((200.0 - 50.0j))
+ assert ae(v, (3.070744996327018106e+84 + 1.7243244846769415903e+84j), tol=ATOL)
+ assert ae(v.real, 3.070744996327018106e+84, tol=PTOL)
+ assert ae(v.imag, 1.7243244846769415903e+84, tol=PTOL)
+ v = fp.ei((320.0 - 80.0j))
+ assert ae(v, (-9.9960598637998647276e+135 + 2.6855081527595608863e+136j), tol=ATOL)
+ assert ae(v.real, -9.9960598637998647276e+135, tol=PTOL)
+ assert ae(v.imag, 2.6855081527595608863e+136, tol=PTOL)
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_functions.py b/lib/python3.10/site-packages/mpmath/tests/test_functions.py
new file mode 100644
index 0000000000000000000000000000000000000000..3bfe852f008173eb636c147abc83d71dbdd4d23a
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_functions.py
@@ -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
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_functions2.py b/lib/python3.10/site-packages/mpmath/tests/test_functions2.py
new file mode 100644
index 0000000000000000000000000000000000000000..2b2d57fcec9be0db4d921b013f24fd6a5e0e9930
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_functions2.py
@@ -0,0 +1,2384 @@
+import math
+import pytest
+from mpmath import *
+
+def test_bessel():
+ mp.dps = 15
+ assert j0(1).ae(0.765197686557966551)
+ assert j0(pi).ae(-0.304242177644093864)
+ assert j0(1000).ae(0.0247866861524201746)
+ assert j0(-25).ae(0.0962667832759581162)
+ assert j1(1).ae(0.440050585744933516)
+ assert j1(pi).ae(0.284615343179752757)
+ assert j1(1000).ae(0.00472831190708952392)
+ assert j1(-25).ae(0.125350249580289905)
+ assert besselj(5,1).ae(0.000249757730211234431)
+ assert besselj(5+0j,1).ae(0.000249757730211234431)
+ assert besselj(5,pi).ae(0.0521411843671184747)
+ assert besselj(5,1000).ae(0.00502540694523318607)
+ assert besselj(5,-25).ae(0.0660079953984229934)
+ assert besselj(-3,2).ae(-0.128943249474402051)
+ assert besselj(-4,2).ae(0.0339957198075684341)
+ assert besselj(3,3+2j).ae(0.424718794929639595942 + 0.625665327745785804812j)
+ assert besselj(0.25,4).ae(-0.374760630804249715)
+ assert besselj(1+2j,3+4j).ae(0.319247428741872131 - 0.669557748880365678j)
+ assert (besselj(3, 10**10) * 10**5).ae(0.76765081748139204023)
+ assert bessely(-0.5, 0) == 0
+ assert bessely(0.5, 0) == -inf
+ assert bessely(1.5, 0) == -inf
+ assert bessely(0,0) == -inf
+ assert bessely(-0.4, 0) == -inf
+ assert bessely(-0.6, 0) == inf
+ assert bessely(-1, 0) == inf
+ assert bessely(-1.4, 0) == inf
+ assert bessely(-1.6, 0) == -inf
+ assert bessely(-1, 0) == inf
+ assert bessely(-2, 0) == -inf
+ assert bessely(-3, 0) == inf
+ assert bessely(0.5, 0) == -inf
+ assert bessely(1, 0) == -inf
+ assert bessely(1.5, 0) == -inf
+ assert bessely(2, 0) == -inf
+ assert bessely(2.5, 0) == -inf
+ assert bessely(3, 0) == -inf
+ assert bessely(0,0.5).ae(-0.44451873350670655715)
+ assert bessely(1,0.5).ae(-1.4714723926702430692)
+ assert bessely(-1,0.5).ae(1.4714723926702430692)
+ assert bessely(3.5,0.5).ae(-138.86400867242488443)
+ assert bessely(0,3+4j).ae(4.6047596915010138655-8.8110771408232264208j)
+ assert bessely(0,j).ae(-0.26803248203398854876+1.26606587775200833560j)
+ assert (bessely(3, 10**10) * 10**5).ae(0.21755917537013204058)
+ assert besseli(0,0) == 1
+ assert besseli(1,0) == 0
+ assert besseli(2,0) == 0
+ assert besseli(-1,0) == 0
+ assert besseli(-2,0) == 0
+ assert besseli(0,0.5).ae(1.0634833707413235193)
+ assert besseli(1,0.5).ae(0.25789430539089631636)
+ assert besseli(-1,0.5).ae(0.25789430539089631636)
+ assert besseli(3.5,0.5).ae(0.00068103597085793815863)
+ assert besseli(0,3+4j).ae(-3.3924877882755196097-1.3239458916287264815j)
+ assert besseli(0,j).ae(besselj(0,1))
+ assert (besseli(3, 10**10) * mpf(10)**(-4342944813)).ae(4.2996028505491271875)
+ assert besselk(0,0) == inf
+ assert besselk(1,0) == inf
+ assert besselk(2,0) == inf
+ assert besselk(-1,0) == inf
+ assert besselk(-2,0) == inf
+ assert besselk(0,0.5).ae(0.92441907122766586178)
+ assert besselk(1,0.5).ae(1.6564411200033008937)
+ assert besselk(-1,0.5).ae(1.6564411200033008937)
+ assert besselk(3.5,0.5).ae(207.48418747548460607)
+ assert besselk(0,3+4j).ae(-0.007239051213570155013+0.026510418350267677215j)
+ assert besselk(0,j).ae(-0.13863371520405399968-1.20196971531720649914j)
+ assert (besselk(3, 10**10) * mpf(10)**4342944824).ae(1.1628981033356187851)
+ # test for issue 331, bug reported by Michael Hartmann
+ for n in range(10,100,10):
+ mp.dps = n
+ assert besseli(91.5,24.7708).ae("4.00830632138673963619656140653537080438462342928377020695738635559218797348548092636896796324190271316137982810144874264e-41")
+
+def test_bessel_zeros():
+ mp.dps = 15
+ assert besseljzero(0,1).ae(2.40482555769577276869)
+ assert besseljzero(2,1).ae(5.1356223018406825563)
+ assert besseljzero(1,50).ae(157.86265540193029781)
+ assert besseljzero(10,1).ae(14.475500686554541220)
+ assert besseljzero(0.5,3).ae(9.4247779607693797153)
+ assert besseljzero(2,1,1).ae(3.0542369282271403228)
+ assert besselyzero(0,1).ae(0.89357696627916752158)
+ assert besselyzero(2,1).ae(3.3842417671495934727)
+ assert besselyzero(1,50).ae(156.29183520147840108)
+ assert besselyzero(10,1).ae(12.128927704415439387)
+ assert besselyzero(0.5,3).ae(7.8539816339744830962)
+ assert besselyzero(2,1,1).ae(5.0025829314460639452)
+
+def test_hankel():
+ mp.dps = 15
+ assert hankel1(0,0.5).ae(0.93846980724081290423-0.44451873350670655715j)
+ assert hankel1(1,0.5).ae(0.2422684576748738864-1.4714723926702430692j)
+ assert hankel1(-1,0.5).ae(-0.2422684576748738864+1.4714723926702430692j)
+ assert hankel1(1.5,0.5).ae(0.0917016996256513026-2.5214655504213378514j)
+ assert hankel1(1.5,3+4j).ae(0.0066806866476728165382-0.0036684231610839127106j)
+ assert hankel2(0,0.5).ae(0.93846980724081290423+0.44451873350670655715j)
+ assert hankel2(1,0.5).ae(0.2422684576748738864+1.4714723926702430692j)
+ assert hankel2(-1,0.5).ae(-0.2422684576748738864-1.4714723926702430692j)
+ assert hankel2(1.5,0.5).ae(0.0917016996256513026+2.5214655504213378514j)
+ assert hankel2(1.5,3+4j).ae(14.783528526098567526-7.397390270853446512j)
+
+def test_struve():
+ mp.dps = 15
+ assert struveh(2,3).ae(0.74238666967748318564)
+ assert struveh(-2.5,3).ae(0.41271003220971599344)
+ assert struvel(2,3).ae(1.7476573277362782744)
+ assert struvel(-2.5,3).ae(1.5153394466819651377)
+
+def test_whittaker():
+ mp.dps = 15
+ assert whitm(2,3,4).ae(49.753745589025246591)
+ assert whitw(2,3,4).ae(14.111656223052932215)
+
+def test_kelvin():
+ mp.dps = 15
+ assert ber(2,3).ae(0.80836846563726819091)
+ assert ber(3,4).ae(-0.28262680167242600233)
+ assert ber(-3,2).ae(-0.085611448496796363669)
+ assert bei(2,3).ae(-0.89102236377977331571)
+ assert bei(-3,2).ae(-0.14420994155731828415)
+ assert ker(2,3).ae(0.12839126695733458928)
+ assert ker(-3,2).ae(-0.29802153400559142783)
+ assert ker(0.5,3).ae(-0.085662378535217097524)
+ assert kei(2,3).ae(0.036804426134164634000)
+ assert kei(-3,2).ae(0.88682069845786731114)
+ assert kei(0.5,3).ae(0.013633041571314302948)
+
+def test_hyper_misc():
+ mp.dps = 15
+ assert hyp0f1(1,0) == 1
+ assert hyp1f1(1,2,0) == 1
+ assert hyp1f2(1,2,3,0) == 1
+ assert hyp2f1(1,2,3,0) == 1
+ assert hyp2f2(1,2,3,4,0) == 1
+ assert hyp2f3(1,2,3,4,5,0) == 1
+ # Degenerate case: 0F0
+ assert hyper([],[],0) == 1
+ assert hyper([],[],-2).ae(exp(-2))
+ # Degenerate case: 1F0
+ assert hyper([2],[],1.5) == 4
+ #
+ assert hyp2f1((1,3),(2,3),(5,6),mpf(27)/32).ae(1.6)
+ assert hyp2f1((1,4),(1,2),(3,4),mpf(80)/81).ae(1.8)
+ assert hyp2f1((2,3),(1,1),(3,2),(2+j)/3).ae(1.327531603558679093+0.439585080092769253j)
+ mp.dps = 25
+ v = mpc('1.2282306665029814734863026', '-0.1225033830118305184672133')
+ assert hyper([(3,4),2+j,1],[1,5,j/3],mpf(1)/5+j/8).ae(v)
+ mp.dps = 15
+
+def test_elliptic_integrals():
+ mp.dps = 15
+ assert ellipk(0).ae(pi/2)
+ assert ellipk(0.5).ae(gamma(0.25)**2/(4*sqrt(pi)))
+ assert ellipk(1) == inf
+ assert ellipk(1+0j) == inf
+ assert ellipk(-1).ae('1.3110287771460599052')
+ assert ellipk(-2).ae('1.1714200841467698589')
+ assert isinstance(ellipk(-2), mpf)
+ assert isinstance(ellipe(-2), mpf)
+ assert ellipk(-50).ae('0.47103424540873331679')
+ mp.dps = 30
+ n1 = +fraction(99999,100000)
+ n2 = +fraction(100001,100000)
+ mp.dps = 15
+ assert ellipk(n1).ae('7.1427724505817781901')
+ assert ellipk(n2).ae(mpc('7.1427417367963090109', '-1.5707923998261688019'))
+ assert ellipe(n1).ae('1.0000332138990829170')
+ v = ellipe(n2)
+ assert v.real.ae('0.999966786328145474069137')
+ assert (v.imag*10**6).ae('7.853952181727432')
+ assert ellipk(2).ae(mpc('1.3110287771460599052', '-1.3110287771460599052'))
+ assert ellipk(50).ae(mpc('0.22326753950210985451', '-0.47434723226254522087'))
+ assert ellipk(3+4j).ae(mpc('0.91119556380496500866', '0.63133428324134524388'))
+ assert ellipk(3-4j).ae(mpc('0.91119556380496500866', '-0.63133428324134524388'))
+ assert ellipk(-3+4j).ae(mpc('0.95357894880405122483', '0.23093044503746114444'))
+ assert ellipk(-3-4j).ae(mpc('0.95357894880405122483', '-0.23093044503746114444'))
+ assert isnan(ellipk(nan))
+ assert isnan(ellipe(nan))
+ assert ellipk(inf) == 0
+ assert isinstance(ellipk(inf), mpc)
+ assert ellipk(-inf) == 0
+ assert ellipk(1+0j) == inf
+ assert ellipe(0).ae(pi/2)
+ assert ellipe(0.5).ae(pi**(mpf(3)/2)/gamma(0.25)**2 +gamma(0.25)**2/(8*sqrt(pi)))
+ assert ellipe(1) == 1
+ assert ellipe(1+0j) == 1
+ assert ellipe(inf) == mpc(0,inf)
+ assert ellipe(-inf) == inf
+ assert ellipe(3+4j).ae(1.4995535209333469543-1.5778790079127582745j)
+ assert ellipe(3-4j).ae(1.4995535209333469543+1.5778790079127582745j)
+ assert ellipe(-3+4j).ae(2.5804237855343377803-0.8306096791000413778j)
+ assert ellipe(-3-4j).ae(2.5804237855343377803+0.8306096791000413778j)
+ assert ellipe(2).ae(0.59907011736779610372+0.59907011736779610372j)
+ assert ellipe('1e-1000000000').ae(pi/2)
+ assert ellipk('1e-1000000000').ae(pi/2)
+ assert ellipe(-pi).ae(2.4535865983838923)
+ mp.dps = 50
+ assert ellipk(1/pi).ae('1.724756270009501831744438120951614673874904182624739673')
+ assert ellipe(1/pi).ae('1.437129808135123030101542922290970050337425479058225712')
+ assert ellipk(-10*pi).ae('0.5519067523886233967683646782286965823151896970015484512')
+ assert ellipe(-10*pi).ae('5.926192483740483797854383268707108012328213431657645509')
+ v = ellipk(pi)
+ assert v.real.ae('0.973089521698042334840454592642137667227167622330325225')
+ assert v.imag.ae('-1.156151296372835303836814390793087600271609993858798016')
+ v = ellipe(pi)
+ assert v.real.ae('0.4632848917264710404078033487934663562998345622611263332')
+ assert v.imag.ae('1.0637961621753130852473300451583414489944099504180510966')
+ mp.dps = 15
+
+def test_exp_integrals():
+ mp.dps = 15
+ x = +e
+ z = e + sqrt(3)*j
+ assert ei(x).ae(8.21168165538361560)
+ assert li(x).ae(1.89511781635593676)
+ assert si(x).ae(1.82104026914756705)
+ assert ci(x).ae(0.213958001340379779)
+ assert shi(x).ae(4.11520706247846193)
+ assert chi(x).ae(4.09647459290515367)
+ assert fresnels(x).ae(0.437189718149787643)
+ assert fresnelc(x).ae(0.401777759590243012)
+ assert airyai(x).ae(0.0108502401568586681)
+ assert airybi(x).ae(8.98245748585468627)
+ assert ei(z).ae(3.72597969491314951 + 7.34213212314224421j)
+ assert li(z).ae(2.28662658112562502 + 1.50427225297269364j)
+ assert si(z).ae(2.48122029237669054 + 0.12684703275254834j)
+ assert ci(z).ae(0.169255590269456633 - 0.892020751420780353j)
+ assert shi(z).ae(1.85810366559344468 + 3.66435842914920263j)
+ assert chi(z).ae(1.86787602931970484 + 3.67777369399304159j)
+ assert fresnels(z/3).ae(0.034534397197008182 + 0.754859844188218737j)
+ assert fresnelc(z/3).ae(1.261581645990027372 + 0.417949198775061893j)
+ assert airyai(z).ae(-0.0162552579839056062 - 0.0018045715700210556j)
+ assert airybi(z).ae(-4.98856113282883371 + 2.08558537872180623j)
+ assert li(0) == 0.0
+ assert li(1) == -inf
+ assert li(inf) == inf
+ assert isinstance(li(0.7), mpf)
+ assert si(inf).ae(pi/2)
+ assert si(-inf).ae(-pi/2)
+ assert ci(inf) == 0
+ assert ci(0) == -inf
+ assert isinstance(ei(-0.7), mpf)
+ assert airyai(inf) == 0
+ assert airybi(inf) == inf
+ assert airyai(-inf) == 0
+ assert airybi(-inf) == 0
+ assert fresnels(inf) == 0.5
+ assert fresnelc(inf) == 0.5
+ assert fresnels(-inf) == -0.5
+ assert fresnelc(-inf) == -0.5
+ assert shi(0) == 0
+ assert shi(inf) == inf
+ assert shi(-inf) == -inf
+ assert chi(0) == -inf
+ assert chi(inf) == inf
+
+def test_ei():
+ mp.dps = 15
+ assert ei(0) == -inf
+ assert ei(inf) == inf
+ assert ei(-inf) == -0.0
+ assert ei(20+70j).ae(6.1041351911152984397e6 - 2.7324109310519928872e6j)
+ # tests for the asymptotic expansion
+ # values checked with Mathematica ExpIntegralEi
+ mp.dps = 50
+ r = ei(20000)
+ s = '3.8781962825045010930273870085501819470698476975019e+8681'
+ assert str(r) == s
+ r = ei(-200)
+ s = '-6.8852261063076355977108174824557929738368086933303e-90'
+ assert str(r) == s
+ r =ei(20000 + 10*j)
+ sre = '-3.255138234032069402493850638874410725961401274106e+8681'
+ sim = '-2.1081929993474403520785942429469187647767369645423e+8681'
+ assert str(r.real) == sre and str(r.imag) == sim
+ mp.dps = 15
+ # More asymptotic expansions
+ assert chi(-10**6+100j).ae('1.3077239389562548386e+434288 + 7.6808956999707408158e+434287j')
+ assert shi(-10**6+100j).ae('-1.3077239389562548386e+434288 - 7.6808956999707408158e+434287j')
+ mp.dps = 15
+ assert ei(10j).ae(-0.0454564330044553726+3.2291439210137706686j)
+ assert ei(100j).ae(-0.0051488251426104921+3.1330217936839529126j)
+ u = ei(fmul(10**20, j, exact=True))
+ assert u.real.ae(-6.4525128526578084421345e-21, abs_eps=0, rel_eps=8*eps)
+ assert u.imag.ae(pi)
+ assert ei(-10j).ae(-0.0454564330044553726-3.2291439210137706686j)
+ assert ei(-100j).ae(-0.0051488251426104921-3.1330217936839529126j)
+ u = ei(fmul(-10**20, j, exact=True))
+ assert u.real.ae(-6.4525128526578084421345e-21, abs_eps=0, rel_eps=8*eps)
+ assert u.imag.ae(-pi)
+ assert ei(10+10j).ae(-1576.1504265768517448+436.9192317011328140j)
+ u = ei(-10+10j)
+ assert u.real.ae(7.6698978415553488362543e-7, abs_eps=0, rel_eps=8*eps)
+ assert u.imag.ae(3.141595611735621062025)
+
+def test_e1():
+ mp.dps = 15
+ assert e1(0) == inf
+ assert e1(inf) == 0
+ assert e1(-inf) == mpc(-inf, -pi)
+ assert e1(10j).ae(0.045456433004455372635 + 0.087551267423977430100j)
+ assert e1(100j).ae(0.0051488251426104921444 - 0.0085708599058403258790j)
+ assert e1(fmul(10**20, j, exact=True)).ae(6.4525128526578084421e-21 - 7.6397040444172830039e-21j, abs_eps=0, rel_eps=8*eps)
+ assert e1(-10j).ae(0.045456433004455372635 - 0.087551267423977430100j)
+ assert e1(-100j).ae(0.0051488251426104921444 + 0.0085708599058403258790j)
+ assert e1(fmul(-10**20, j, exact=True)).ae(6.4525128526578084421e-21 + 7.6397040444172830039e-21j, abs_eps=0, rel_eps=8*eps)
+
+def test_expint():
+ mp.dps = 15
+ assert expint(0,0) == inf
+ assert expint(0,1).ae(1/e)
+ assert expint(0,1.5).ae(2/exp(1.5)/3)
+ assert expint(1,1).ae(-ei(-1))
+ assert expint(2,0).ae(1)
+ assert expint(3,0).ae(1/2.)
+ assert expint(4,0).ae(1/3.)
+ assert expint(-2, 0.5).ae(26/sqrt(e))
+ assert expint(-1,-1) == 0
+ assert expint(-2,-1).ae(-e)
+ assert expint(5.5, 0).ae(2/9.)
+ assert expint(2.00000001,0).ae(100000000./100000001)
+ assert expint(2+3j,4-j).ae(0.0023461179581675065414+0.0020395540604713669262j)
+ assert expint('1.01', '1e-1000').ae(99.9999999899412802)
+ assert expint('1.000000000001', 3.5).ae(0.00697013985754701819446)
+ assert expint(2,3).ae(3*ei(-3)+exp(-3))
+ assert (expint(10,20)*10**10).ae(0.694439055541231353)
+ assert expint(3,inf) == 0
+ assert expint(3.2,inf) == 0
+ assert expint(3.2+2j,inf) == 0
+ assert expint(1,3j).ae(-0.11962978600800032763 + 0.27785620120457163717j)
+ assert expint(1,3).ae(0.013048381094197037413)
+ assert expint(1,-3).ae(-ei(3)-pi*j)
+ #assert expint(3) == expint(1,3)
+ assert expint(1,-20).ae(-25615652.66405658882 - 3.1415926535897932385j)
+ assert expint(1000000,0).ae(1./999999)
+ assert expint(0,2+3j).ae(-0.025019798357114678171 + 0.027980439405104419040j)
+ assert expint(-1,2+3j).ae(-0.022411973626262070419 + 0.038058922011377716932j)
+ assert expint(-1.5,0) == inf
+
+def test_trig_integrals():
+ mp.dps = 30
+ assert si(mpf(1)/1000000).ae('0.000000999999999999944444444444446111')
+ assert ci(mpf(1)/1000000).ae('-13.2382948930629912435014366276')
+ assert si(10**10).ae('1.5707963267075846569685111517747537')
+ assert ci(10**10).ae('-4.87506025174822653785729773959e-11')
+ assert si(10**100).ae(pi/2)
+ assert (ci(10**100)*10**100).ae('-0.372376123661276688262086695553')
+ assert si(-3) == -si(3)
+ assert ci(-3).ae(ci(3) + pi*j)
+ # Test complex structure
+ mp.dps = 15
+ assert mp.ci(50).ae(-0.0056283863241163054402)
+ assert mp.ci(50+2j).ae(-0.018378282946133067149+0.070352808023688336193j)
+ assert mp.ci(20j).ae(1.28078263320282943611e7+1.5707963267949j)
+ assert mp.ci(-2+20j).ae(-4.050116856873293505e6+1.207476188206989909e7j)
+ assert mp.ci(-50+2j).ae(-0.0183782829461330671+3.0712398455661049023j)
+ assert mp.ci(-50).ae(-0.0056283863241163054+3.1415926535897932385j)
+ assert mp.ci(-50-2j).ae(-0.0183782829461330671-3.0712398455661049023j)
+ assert mp.ci(-2-20j).ae(-4.050116856873293505e6-1.207476188206989909e7j)
+ assert mp.ci(-20j).ae(1.28078263320282943611e7-1.5707963267949j)
+ assert mp.ci(50-2j).ae(-0.018378282946133067149-0.070352808023688336193j)
+ assert mp.si(50).ae(1.5516170724859358947)
+ assert mp.si(50+2j).ae(1.497884414277228461-0.017515007378437448j)
+ assert mp.si(20j).ae(1.2807826332028294459e7j)
+ assert mp.si(-2+20j).ae(-1.20747603112735722103e7-4.050116856873293554e6j)
+ assert mp.si(-50+2j).ae(-1.497884414277228461-0.017515007378437448j)
+ assert mp.si(-50).ae(-1.5516170724859358947)
+ assert mp.si(-50-2j).ae(-1.497884414277228461+0.017515007378437448j)
+ assert mp.si(-2-20j).ae(-1.20747603112735722103e7+4.050116856873293554e6j)
+ assert mp.si(-20j).ae(-1.2807826332028294459e7j)
+ assert mp.si(50-2j).ae(1.497884414277228461+0.017515007378437448j)
+ assert mp.chi(50j).ae(-0.0056283863241163054+1.5707963267948966192j)
+ assert mp.chi(-2+50j).ae(-0.0183782829461330671+1.6411491348185849554j)
+ assert mp.chi(-20).ae(1.28078263320282943611e7+3.1415926535898j)
+ assert mp.chi(-20-2j).ae(-4.050116856873293505e6+1.20747571696809187053e7j)
+ assert mp.chi(-2-50j).ae(-0.0183782829461330671-1.6411491348185849554j)
+ assert mp.chi(-50j).ae(-0.0056283863241163054-1.5707963267948966192j)
+ assert mp.chi(2-50j).ae(-0.0183782829461330671-1.500443518771208283j)
+ assert mp.chi(20-2j).ae(-4.050116856873293505e6-1.20747603112735722951e7j)
+ assert mp.chi(20).ae(1.2807826332028294361e7)
+ assert mp.chi(2+50j).ae(-0.0183782829461330671+1.500443518771208283j)
+ assert mp.shi(50j).ae(1.5516170724859358947j)
+ assert mp.shi(-2+50j).ae(0.017515007378437448+1.497884414277228461j)
+ assert mp.shi(-20).ae(-1.2807826332028294459e7)
+ assert mp.shi(-20-2j).ae(4.050116856873293554e6-1.20747603112735722103e7j)
+ assert mp.shi(-2-50j).ae(0.017515007378437448-1.497884414277228461j)
+ assert mp.shi(-50j).ae(-1.5516170724859358947j)
+ assert mp.shi(2-50j).ae(-0.017515007378437448-1.497884414277228461j)
+ assert mp.shi(20-2j).ae(-4.050116856873293554e6-1.20747603112735722103e7j)
+ assert mp.shi(20).ae(1.2807826332028294459e7)
+ assert mp.shi(2+50j).ae(-0.017515007378437448+1.497884414277228461j)
+ def ae(x,y,tol=1e-12):
+ return abs(x-y) <= abs(y)*tol
+ assert fp.ci(fp.inf) == 0
+ assert ae(fp.ci(fp.ninf), fp.pi*1j)
+ assert ae(fp.si(fp.inf), fp.pi/2)
+ assert ae(fp.si(fp.ninf), -fp.pi/2)
+ assert fp.si(0) == 0
+ assert ae(fp.ci(50), -0.0056283863241163054402)
+ assert ae(fp.ci(50+2j), -0.018378282946133067149+0.070352808023688336193j)
+ assert ae(fp.ci(20j), 1.28078263320282943611e7+1.5707963267949j)
+ assert ae(fp.ci(-2+20j), -4.050116856873293505e6+1.207476188206989909e7j)
+ assert ae(fp.ci(-50+2j), -0.0183782829461330671+3.0712398455661049023j)
+ assert ae(fp.ci(-50), -0.0056283863241163054+3.1415926535897932385j)
+ assert ae(fp.ci(-50-2j), -0.0183782829461330671-3.0712398455661049023j)
+ assert ae(fp.ci(-2-20j), -4.050116856873293505e6-1.207476188206989909e7j)
+ assert ae(fp.ci(-20j), 1.28078263320282943611e7-1.5707963267949j)
+ assert ae(fp.ci(50-2j), -0.018378282946133067149-0.070352808023688336193j)
+ assert ae(fp.si(50), 1.5516170724859358947)
+ assert ae(fp.si(50+2j), 1.497884414277228461-0.017515007378437448j)
+ assert ae(fp.si(20j), 1.2807826332028294459e7j)
+ assert ae(fp.si(-2+20j), -1.20747603112735722103e7-4.050116856873293554e6j)
+ assert ae(fp.si(-50+2j), -1.497884414277228461-0.017515007378437448j)
+ assert ae(fp.si(-50), -1.5516170724859358947)
+ assert ae(fp.si(-50-2j), -1.497884414277228461+0.017515007378437448j)
+ assert ae(fp.si(-2-20j), -1.20747603112735722103e7+4.050116856873293554e6j)
+ assert ae(fp.si(-20j), -1.2807826332028294459e7j)
+ assert ae(fp.si(50-2j), 1.497884414277228461+0.017515007378437448j)
+ assert ae(fp.chi(50j), -0.0056283863241163054+1.5707963267948966192j)
+ assert ae(fp.chi(-2+50j), -0.0183782829461330671+1.6411491348185849554j)
+ assert ae(fp.chi(-20), 1.28078263320282943611e7+3.1415926535898j)
+ assert ae(fp.chi(-20-2j), -4.050116856873293505e6+1.20747571696809187053e7j)
+ assert ae(fp.chi(-2-50j), -0.0183782829461330671-1.6411491348185849554j)
+ assert ae(fp.chi(-50j), -0.0056283863241163054-1.5707963267948966192j)
+ assert ae(fp.chi(2-50j), -0.0183782829461330671-1.500443518771208283j)
+ assert ae(fp.chi(20-2j), -4.050116856873293505e6-1.20747603112735722951e7j)
+ assert ae(fp.chi(20), 1.2807826332028294361e7)
+ assert ae(fp.chi(2+50j), -0.0183782829461330671+1.500443518771208283j)
+ assert ae(fp.shi(50j), 1.5516170724859358947j)
+ assert ae(fp.shi(-2+50j), 0.017515007378437448+1.497884414277228461j)
+ assert ae(fp.shi(-20), -1.2807826332028294459e7)
+ assert ae(fp.shi(-20-2j), 4.050116856873293554e6-1.20747603112735722103e7j)
+ assert ae(fp.shi(-2-50j), 0.017515007378437448-1.497884414277228461j)
+ assert ae(fp.shi(-50j), -1.5516170724859358947j)
+ assert ae(fp.shi(2-50j), -0.017515007378437448-1.497884414277228461j)
+ assert ae(fp.shi(20-2j), -4.050116856873293554e6-1.20747603112735722103e7j)
+ assert ae(fp.shi(20), 1.2807826332028294459e7)
+ assert ae(fp.shi(2+50j), -0.017515007378437448+1.497884414277228461j)
+
+def test_airy():
+ mp.dps = 15
+ assert (airyai(10)*10**10).ae(1.1047532552898687)
+ assert (airybi(10)/10**9).ae(0.45564115354822515)
+ assert (airyai(1000)*10**9158).ae(9.306933063179556004)
+ assert (airybi(1000)/10**9154).ae(5.4077118391949465477)
+ assert airyai(-1000).ae(0.055971895773019918842)
+ assert airybi(-1000).ae(-0.083264574117080633012)
+ assert (airyai(100+100j)*10**188).ae(2.9099582462207032076 + 2.353013591706178756j)
+ assert (airybi(100+100j)/10**185).ae(1.7086751714463652039 - 3.1416590020830804578j)
+
+def test_hyper_0f1():
+ mp.dps = 15
+ v = 8.63911136507950465
+ assert hyper([],[(1,3)],1.5).ae(v)
+ assert hyper([],[1/3.],1.5).ae(v)
+ assert hyp0f1(1/3.,1.5).ae(v)
+ assert hyp0f1((1,3),1.5).ae(v)
+ # Asymptotic expansion
+ assert hyp0f1(3,1e9).ae('4.9679055380347771271e+27455')
+ assert hyp0f1(3,1e9j).ae('-2.1222788784457702157e+19410 + 5.0840597555401854116e+19410j')
+
+def test_hyper_1f1():
+ mp.dps = 15
+ v = 1.2917526488617656673
+ assert hyper([(1,2)],[(3,2)],0.7).ae(v)
+ assert hyper([(1,2)],[(3,2)],0.7+0j).ae(v)
+ assert hyper([0.5],[(3,2)],0.7).ae(v)
+ assert hyper([0.5],[1.5],0.7).ae(v)
+ assert hyper([0.5],[(3,2)],0.7+0j).ae(v)
+ assert hyper([0.5],[1.5],0.7+0j).ae(v)
+ assert hyper([(1,2)],[1.5+0j],0.7).ae(v)
+ assert hyper([0.5+0j],[1.5],0.7).ae(v)
+ assert hyper([0.5+0j],[1.5+0j],0.7+0j).ae(v)
+ assert hyp1f1(0.5,1.5,0.7).ae(v)
+ assert hyp1f1((1,2),1.5,0.7).ae(v)
+ # Asymptotic expansion
+ assert hyp1f1(2,3,1e10).ae('2.1555012157015796988e+4342944809')
+ assert (hyp1f1(2,3,1e10j)*10**10).ae(-0.97501205020039745852 - 1.7462392454512132074j)
+ # Shouldn't use asymptotic expansion
+ assert hyp1f1(-2, 1, 10000).ae(49980001)
+ # Bug
+ assert hyp1f1(1j,fraction(1,3),0.415-69.739j).ae(25.857588206024346592 + 15.738060264515292063j)
+
+def test_hyper_2f1():
+ mp.dps = 15
+ v = 1.0652207633823291032
+ assert hyper([(1,2), (3,4)], [2], 0.3).ae(v)
+ assert hyper([(1,2), 0.75], [2], 0.3).ae(v)
+ assert hyper([0.5, 0.75], [2.0], 0.3).ae(v)
+ assert hyper([0.5, 0.75], [2.0], 0.3+0j).ae(v)
+ assert hyper([0.5+0j, (3,4)], [2.0], 0.3+0j).ae(v)
+ assert hyper([0.5+0j, (3,4)], [2.0], 0.3).ae(v)
+ assert hyper([0.5, (3,4)], [2.0+0j], 0.3).ae(v)
+ assert hyper([0.5+0j, 0.75+0j], [2.0+0j], 0.3+0j).ae(v)
+ v = 1.09234681096223231717 + 0.18104859169479360380j
+ assert hyper([(1,2),0.75+j], [2], 0.5).ae(v)
+ assert hyper([0.5,0.75+j], [2.0], 0.5).ae(v)
+ assert hyper([0.5,0.75+j], [2.0], 0.5+0j).ae(v)
+ assert hyper([0.5,0.75+j], [2.0+0j], 0.5+0j).ae(v)
+ v = 0.9625 - 0.125j
+ assert hyper([(3,2),-1],[4], 0.1+j/3).ae(v)
+ assert hyper([1.5,-1.0],[4], 0.1+j/3).ae(v)
+ assert hyper([1.5,-1.0],[4+0j], 0.1+j/3).ae(v)
+ assert hyper([1.5+0j,-1.0+0j],[4+0j], 0.1+j/3).ae(v)
+ v = 1.02111069501693445001 - 0.50402252613466859521j
+ assert hyper([(2,10),(3,10)],[(4,10)],1.5).ae(v)
+ assert hyper([0.2,(3,10)],[0.4+0j],1.5).ae(v)
+ assert hyper([0.2,(3,10)],[0.4+0j],1.5+0j).ae(v)
+ v = 0.76922501362865848528 + 0.32640579593235886194j
+ assert hyper([(2,10),(3,10)],[(4,10)],4+2j).ae(v)
+ assert hyper([0.2,(3,10)],[0.4+0j],4+2j).ae(v)
+ assert hyper([0.2,(3,10)],[(4,10)],4+2j).ae(v)
+
+def test_hyper_2f1_hard():
+ mp.dps = 15
+ # Singular cases
+ assert hyp2f1(2,-1,-1,3).ae(7)
+ assert hyp2f1(2,-1,-1,3,eliminate_all=True).ae(0.25)
+ assert hyp2f1(2,-2,-2,3).ae(34)
+ assert hyp2f1(2,-2,-2,3,eliminate_all=True).ae(0.25)
+ assert hyp2f1(2,-2,-3,3) == 14
+ assert hyp2f1(2,-3,-2,3) == inf
+ assert hyp2f1(2,-1.5,-1.5,3) == 0.25
+ assert hyp2f1(1,2,3,0) == 1
+ assert hyp2f1(0,1,0,0) == 1
+ assert hyp2f1(0,0,0,0) == 1
+ assert isnan(hyp2f1(1,1,0,0))
+ assert hyp2f1(2,-1,-5, 0.25+0.25j).ae(1.1+0.1j)
+ assert hyp2f1(2,-5,-5, 0.25+0.25j, eliminate=False).ae(163./128 + 125./128*j)
+ assert hyp2f1(0.7235, -1, -5, 0.3).ae(1.04341)
+ assert hyp2f1(0.7235, -5, -5, 0.3, eliminate=False).ae(1.2939225017815903812)
+ assert hyp2f1(-1,-2,4,1) == 1.5
+ assert hyp2f1(1,2,-3,1) == inf
+ assert hyp2f1(-2,-2,1,1) == 6
+ assert hyp2f1(1,-2,-4,1).ae(5./3)
+ assert hyp2f1(0,-6,-4,1) == 1
+ assert hyp2f1(0,-3,-4,1) == 1
+ assert hyp2f1(0,0,0,1) == 1
+ assert hyp2f1(1,0,0,1,eliminate=False) == 1
+ assert hyp2f1(1,1,0,1) == inf
+ assert hyp2f1(1,-6,-4,1) == inf
+ assert hyp2f1(-7.2,-0.5,-4.5,1) == 0
+ assert hyp2f1(-7.2,-1,-2,1).ae(-2.6)
+ assert hyp2f1(1,-0.5,-4.5, 1) == inf
+ assert hyp2f1(1,0.5,-4.5, 1) == -inf
+ # Check evaluation on / close to unit circle
+ z = exp(j*pi/3)
+ w = (nthroot(2,3)+1)*exp(j*pi/12)/nthroot(3,4)**3
+ assert hyp2f1('1/2','1/6','1/3', z).ae(w)
+ assert hyp2f1('1/2','1/6','1/3', z.conjugate()).ae(w.conjugate())
+ assert hyp2f1(0.25, (1,3), 2, '0.999').ae(1.06826449496030635)
+ assert hyp2f1(0.25, (1,3), 2, '1.001').ae(1.06867299254830309446-0.00001446586793975874j)
+ assert hyp2f1(0.25, (1,3), 2, -1).ae(0.96656584492524351673)
+ assert hyp2f1(0.25, (1,3), 2, j).ae(0.99041766248982072266+0.03777135604180735522j)
+ assert hyp2f1(2,3,5,'0.99').ae(27.699347904322690602)
+ assert hyp2f1((3,2),-0.5,3,'0.99').ae(0.68403036843911661388)
+ assert hyp2f1(2,3,5,1j).ae(0.37290667145974386127+0.59210004902748285917j)
+ assert fsum([hyp2f1((7,10),(2,3),(-1,2), 0.95*exp(j*k)) for k in range(1,15)]).ae(52.851400204289452922+6.244285013912953225j)
+ assert fsum([hyp2f1((7,10),(2,3),(-1,2), 1.05*exp(j*k)) for k in range(1,15)]).ae(54.506013786220655330-3.000118813413217097j)
+ assert fsum([hyp2f1((7,10),(2,3),(-1,2), exp(j*k)) for k in range(1,15)]).ae(55.792077935955314887+1.731986485778500241j)
+ assert hyp2f1(2,2.5,-3.25,0.999).ae(218373932801217082543180041.33)
+ # Branches
+ assert hyp2f1(1,1,2,1.01).ae(4.5595744415723676911-3.1104877758314784539j)
+ assert hyp2f1(1,1,2,1.01+0.1j).ae(2.4149427480552782484+1.4148224796836938829j)
+ assert hyp2f1(1,1,2,3+4j).ae(0.14576709331407297807+0.48379185417980360773j)
+ assert hyp2f1(1,1,2,4).ae(-0.27465307216702742285 - 0.78539816339744830962j)
+ assert hyp2f1(1,1,2,-4).ae(0.40235947810852509365)
+ # Other:
+ # Cancellation with a large parameter involved (bug reported on sage-devel)
+ assert hyp2f1(112, (51,10), (-9,10), -0.99999).ae(-1.6241361047970862961e-24, abs_eps=0, rel_eps=eps*16)
+
+def test_hyper_3f2_etc():
+ assert hyper([1,2,3],[1.5,8],-1).ae(0.67108992351533333030)
+ assert hyper([1,2,3,4],[5,6,7], -1).ae(0.90232988035425506008)
+ assert hyper([1,2,3],[1.25,5], 1).ae(28.924181329701905701)
+ assert hyper([1,2,3,4],[5,6,7],5).ae(1.5192307344006649499-1.1529845225075537461j)
+ assert hyper([1,2,3,4,5],[6,7,8,9],-1).ae(0.96288759462882357253)
+ assert hyper([1,2,3,4,5],[6,7,8,9],1).ae(1.0428697385885855841)
+ assert hyper([1,2,3,4,5],[6,7,8,9],5).ae(1.33980653631074769423-0.07143405251029226699j)
+ assert hyper([1,2.79,3.08,4.37],[5.2,6.1,7.3],5).ae(1.0996321464692607231-1.7748052293979985001j)
+ assert hyper([1,1,1],[1,2],1) == inf
+ assert hyper([1,1,1],[2,(101,100)],1).ae(100.01621213528313220)
+ # slow -- covered by doctests
+ #assert hyper([1,1,1],[2,3],0.9999).ae(1.2897972005319693905)
+
+def test_hyper_u():
+ mp.dps = 15
+ assert hyperu(2,-3,0).ae(0.05)
+ assert hyperu(2,-3.5,0).ae(4./99)
+ assert hyperu(2,0,0) == 0.5
+ assert hyperu(-5,1,0) == -120
+ assert hyperu(-5,2,0) == inf
+ assert hyperu(-5,-2,0) == 0
+ assert hyperu(7,7,3).ae(0.00014681269365593503986) #exp(3)*gammainc(-6,3)
+ assert hyperu(2,-3,4).ae(0.011836478100271995559)
+ assert hyperu(3,4,5).ae(1./125)
+ assert hyperu(2,3,0.0625) == 256
+ assert hyperu(-1,2,0.25+0.5j) == -1.75+0.5j
+ assert hyperu(0.5,1.5,7.25).ae(2/sqrt(29))
+ assert hyperu(2,6,pi).ae(0.55804439825913399130)
+ assert (hyperu((3,2),8,100+201j)*10**4).ae(-0.3797318333856738798 - 2.9974928453561707782j)
+ assert (hyperu((5,2),(-1,2),-5000)*10**10).ae(-5.6681877926881664678j)
+ # XXX: fails because of undetected cancellation in low level series code
+ # Alternatively: could use asymptotic series here, if convergence test
+ # tweaked back to recognize this one
+ #assert (hyperu((5,2),(-1,2),-500)*10**7).ae(-1.82526906001593252847j)
+
+def test_hyper_2f0():
+ mp.dps = 15
+ assert hyper([1,2],[],3) == hyp2f0(1,2,3)
+ assert hyp2f0(2,3,7).ae(0.0116108068639728714668 - 0.0073727413865865802130j)
+ assert hyp2f0(2,3,0) == 1
+ assert hyp2f0(0,0,0) == 1
+ assert hyp2f0(-1,-1,1).ae(2)
+ assert hyp2f0(-4,1,1.5).ae(62.5)
+ assert hyp2f0(-4,1,50).ae(147029801)
+ assert hyp2f0(-4,1,0.0001).ae(0.99960011997600240000)
+ assert hyp2f0(0.5,0.25,0.001).ae(1.0001251174078538115)
+ assert hyp2f0(0.5,0.25,3+4j).ae(0.85548875824755163518 + 0.21636041283392292973j)
+ # Important: cancellation check
+ assert hyp2f0((1,6),(5,6),-0.02371708245126284498).ae(0.996785723120804309)
+ # Should be exact; polynomial case
+ assert hyp2f0(-2,1,0.5+0.5j,zeroprec=200) == 0
+ assert hyp2f0(1,-2,0.5+0.5j,zeroprec=200) == 0
+ # There used to be a bug in thresholds that made one of the following hang
+ for d in [15, 50, 80]:
+ mp.dps = d
+ assert hyp2f0(1.5, 0.5, 0.009).ae('1.006867007239309717945323585695344927904000945829843527398772456281301440034218290443367270629519483 + 1.238277162240704919639384945859073461954721356062919829456053965502443570466701567100438048602352623e-46j')
+
+def test_hyper_1f2():
+ mp.dps = 15
+ assert hyper([1],[2,3],4) == hyp1f2(1,2,3,4)
+ a1,b1,b2 = (1,10),(2,3),1./16
+ assert hyp1f2(a1,b1,b2,10).ae(298.7482725554557568)
+ assert hyp1f2(a1,b1,b2,100).ae(224128961.48602947604)
+ assert hyp1f2(a1,b1,b2,1000).ae(1.1669528298622675109e+27)
+ assert hyp1f2(a1,b1,b2,10000).ae(2.4780514622487212192e+86)
+ assert hyp1f2(a1,b1,b2,100000).ae(1.3885391458871523997e+274)
+ assert hyp1f2(a1,b1,b2,1000000).ae('9.8851796978960318255e+867')
+ assert hyp1f2(a1,b1,b2,10**7).ae('1.1505659189516303646e+2746')
+ assert hyp1f2(a1,b1,b2,10**8).ae('1.4672005404314334081e+8685')
+ assert hyp1f2(a1,b1,b2,10**20).ae('3.6888217332150976493e+8685889636')
+ assert hyp1f2(a1,b1,b2,10*j).ae(-16.163252524618572878 - 44.321567896480184312j)
+ assert hyp1f2(a1,b1,b2,100*j).ae(61938.155294517848171 + 637349.45215942348739j)
+ assert hyp1f2(a1,b1,b2,1000*j).ae(8455057657257695958.7 + 6261969266997571510.6j)
+ assert hyp1f2(a1,b1,b2,10000*j).ae(-8.9771211184008593089e+60 + 4.6550528111731631456e+59j)
+ assert hyp1f2(a1,b1,b2,100000*j).ae(2.6398091437239324225e+193 + 4.1658080666870618332e+193j)
+ assert hyp1f2(a1,b1,b2,1000000*j).ae('3.5999042951925965458e+613 + 1.5026014707128947992e+613j')
+ assert hyp1f2(a1,b1,b2,10**7*j).ae('-8.3208715051623234801e+1939 - 3.6752883490851869429e+1941j')
+ assert hyp1f2(a1,b1,b2,10**8*j).ae('2.0724195707891484454e+6140 - 1.3276619482724266387e+6141j')
+ assert hyp1f2(a1,b1,b2,10**20*j).ae('-1.1734497974795488504e+6141851462 + 1.1498106965385471542e+6141851462j')
+
+def test_hyper_2f3():
+ mp.dps = 15
+ assert hyper([1,2],[3,4,5],6) == hyp2f3(1,2,3,4,5,6)
+ a1,a2,b1,b2,b3 = (1,10),(2,3),(3,10), 2, 1./16
+ # Check asymptotic expansion
+ assert hyp2f3(a1,a2,b1,b2,b3,10).ae(128.98207160698659976)
+ assert hyp2f3(a1,a2,b1,b2,b3,1000).ae(6.6309632883131273141e25)
+ assert hyp2f3(a1,a2,b1,b2,b3,10000).ae(4.6863639362713340539e84)
+ assert hyp2f3(a1,a2,b1,b2,b3,100000).ae(8.6632451236103084119e271)
+ assert hyp2f3(a1,a2,b1,b2,b3,10**6).ae('2.0291718386574980641e865')
+ assert hyp2f3(a1,a2,b1,b2,b3,10**7).ae('7.7639836665710030977e2742')
+ assert hyp2f3(a1,a2,b1,b2,b3,10**8).ae('3.2537462584071268759e8681')
+ assert hyp2f3(a1,a2,b1,b2,b3,10**20).ae('1.2966030542911614163e+8685889627')
+ assert hyp2f3(a1,a2,b1,b2,b3,10*j).ae(-18.551602185587547854 - 13.348031097874113552j)
+ assert hyp2f3(a1,a2,b1,b2,b3,100*j).ae(78634.359124504488695 + 74459.535945281973996j)
+ assert hyp2f3(a1,a2,b1,b2,b3,1000*j).ae(597682550276527901.59 - 65136194809352613.078j)
+ assert hyp2f3(a1,a2,b1,b2,b3,10000*j).ae(-1.1779696326238582496e+59 + 1.2297607505213133872e+59j)
+ assert hyp2f3(a1,a2,b1,b2,b3,100000*j).ae(2.9844228969804380301e+191 + 7.5587163231490273296e+190j)
+ assert hyp2f3(a1,a2,b1,b2,b3,1000000*j).ae('7.4859161049322370311e+610 - 2.8467477015940090189e+610j')
+ assert hyp2f3(a1,a2,b1,b2,b3,10**7*j).ae('-1.7477645579418800826e+1938 - 1.7606522995808116405e+1938j')
+ assert hyp2f3(a1,a2,b1,b2,b3,10**8*j).ae('-1.6932731942958401784e+6137 - 2.4521909113114629368e+6137j')
+ assert hyp2f3(a1,a2,b1,b2,b3,10**20*j).ae('-2.0988815677627225449e+6141851451 + 5.7708223542739208681e+6141851452j')
+
+def test_hyper_2f2():
+ mp.dps = 15
+ assert hyper([1,2],[3,4],5) == hyp2f2(1,2,3,4,5)
+ a1,a2,b1,b2 = (3,10),4,(1,2),1./16
+ assert hyp2f2(a1,a2,b1,b2,10).ae(448225936.3377556696)
+ assert hyp2f2(a1,a2,b1,b2,10000).ae('1.2012553712966636711e+4358')
+ assert hyp2f2(a1,a2,b1,b2,-20000).ae(-0.04182343755661214626)
+ assert hyp2f2(a1,a2,b1,b2,10**20).ae('1.1148680024303263661e+43429448190325182840')
+
+def test_orthpoly():
+ mp.dps = 15
+ assert jacobi(-4,2,3,0.7).ae(22800./4913)
+ assert jacobi(3,2,4,5.5) == 4133.125
+ assert jacobi(1.5,5/6.,4,0).ae(-1.0851951434075508417)
+ assert jacobi(-2, 1, 2, 4).ae(-0.16)
+ assert jacobi(2, -1, 2.5, 4).ae(34.59375)
+ #assert jacobi(2, -1, 2, 4) == 28.5
+ assert legendre(5, 7) == 129367
+ assert legendre(0.5,0).ae(0.53935260118837935667)
+ assert legendre(-1,-1) == 1
+ assert legendre(0,-1) == 1
+ assert legendre(0, 1) == 1
+ assert legendre(1, -1) == -1
+ assert legendre(7, 1) == 1
+ assert legendre(7, -1) == -1
+ assert legendre(8,1.5).ae(15457523./32768)
+ assert legendre(j,-j).ae(2.4448182735671431011 + 0.6928881737669934843j)
+ assert chebyu(5,1) == 6
+ assert chebyt(3,2) == 26
+ assert legendre(3.5,-1) == inf
+ assert legendre(4.5,-1) == -inf
+ assert legendre(3.5+1j,-1) == mpc(inf,inf)
+ assert legendre(4.5+1j,-1) == mpc(-inf,-inf)
+ assert laguerre(4, -2, 3).ae(-1.125)
+ assert laguerre(3, 1+j, 0.5).ae(0.2291666666666666667 + 2.5416666666666666667j)
+
+def test_hermite():
+ mp.dps = 15
+ assert hermite(-2, 0).ae(0.5)
+ assert hermite(-1, 0).ae(0.88622692545275801365)
+ assert hermite(0, 0).ae(1)
+ assert hermite(1, 0) == 0
+ assert hermite(2, 0).ae(-2)
+ assert hermite(0, 2).ae(1)
+ assert hermite(1, 2).ae(4)
+ assert hermite(1, -2).ae(-4)
+ assert hermite(2, -2).ae(14)
+ assert hermite(0.5, 0).ae(0.69136733903629335053)
+ assert hermite(9, 0) == 0
+ assert hermite(4,4).ae(3340)
+ assert hermite(3,4).ae(464)
+ assert hermite(-4,4).ae(0.00018623860287512396181)
+ assert hermite(-3,4).ae(0.0016540169879668766270)
+ assert hermite(9, 2.5j).ae(13638725j)
+ assert hermite(9, -2.5j).ae(-13638725j)
+ assert hermite(9, 100).ae(511078883759363024000)
+ assert hermite(9, -100).ae(-511078883759363024000)
+ assert hermite(9, 100j).ae(512922083920643024000j)
+ assert hermite(9, -100j).ae(-512922083920643024000j)
+ assert hermite(-9.5, 2.5j).ae(-2.9004951258126778174e-6 + 1.7601372934039951100e-6j)
+ assert hermite(-9.5, -2.5j).ae(-2.9004951258126778174e-6 - 1.7601372934039951100e-6j)
+ assert hermite(-9.5, 100).ae(1.3776300722767084162e-22, abs_eps=0, rel_eps=eps)
+ assert hermite(-9.5, -100).ae('1.3106082028470671626e4355')
+ assert hermite(-9.5, 100j).ae(-9.7900218581864768430e-23 - 9.7900218581864768430e-23j, abs_eps=0, rel_eps=eps)
+ assert hermite(-9.5, -100j).ae(-9.7900218581864768430e-23 + 9.7900218581864768430e-23j, abs_eps=0, rel_eps=eps)
+ assert hermite(2+3j, -1-j).ae(851.3677063883687676 - 1496.4373467871007997j)
+
+def test_gegenbauer():
+ mp.dps = 15
+ assert gegenbauer(1,2,3).ae(12)
+ assert gegenbauer(2,3,4).ae(381)
+ assert gegenbauer(0,0,0) == 0
+ assert gegenbauer(2,-1,3) == 0
+ assert gegenbauer(-7, 0.5, 3).ae(8989)
+ assert gegenbauer(1, -0.5, 3).ae(-3)
+ assert gegenbauer(1, -1.5, 3).ae(-9)
+ assert gegenbauer(1, -0.5, 3).ae(-3)
+ assert gegenbauer(-0.5, -0.5, 3).ae(-2.6383553159023906245)
+ assert gegenbauer(2+3j, 1-j, 3+4j).ae(14.880536623203696780 + 20.022029711598032898j)
+ #assert gegenbauer(-2, -0.5, 3).ae(-12)
+
+def test_legenp():
+ mp.dps = 15
+ assert legenp(2,0,4) == legendre(2,4)
+ assert legenp(-2, -1, 0.5).ae(0.43301270189221932338)
+ assert legenp(-2, -1, 0.5, type=3).ae(0.43301270189221932338j)
+ assert legenp(-2, 1, 0.5).ae(-0.86602540378443864676)
+ assert legenp(2+j, 3+4j, -j).ae(134742.98773236786148 + 429782.72924463851745j)
+ assert legenp(2+j, 3+4j, -j, type=3).ae(802.59463394152268507 - 251.62481308942906447j)
+ assert legenp(2,4,3).ae(0)
+ assert legenp(2,4,3,type=3).ae(0)
+ assert legenp(2,1,0.5).ae(-1.2990381056766579701)
+ assert legenp(2,1,0.5,type=3).ae(1.2990381056766579701j)
+ assert legenp(3,2,3).ae(-360)
+ assert legenp(3,3,3).ae(240j*2**0.5)
+ assert legenp(3,4,3).ae(0)
+ assert legenp(0,0.5,2).ae(0.52503756790433198939 - 0.52503756790433198939j)
+ assert legenp(-1,-0.5,2).ae(0.60626116232846498110 + 0.60626116232846498110j)
+ assert legenp(-2,0.5,2).ae(1.5751127037129959682 - 1.5751127037129959682j)
+ assert legenp(-2,0.5,-0.5).ae(-0.85738275810499171286)
+
+def test_legenq():
+ mp.dps = 15
+ f = legenq
+ # Evaluation at poles
+ assert isnan(f(3,2,1))
+ assert isnan(f(3,2,-1))
+ assert isnan(f(3,2,1,type=3))
+ assert isnan(f(3,2,-1,type=3))
+ # Evaluation at 0
+ assert f(0,1,0,type=2).ae(-1)
+ assert f(-2,2,0,type=2,zeroprec=200).ae(0)
+ assert f(1.5,3,0,type=2).ae(-2.2239343475841951023)
+ assert f(0,1,0,type=3).ae(j)
+ assert f(-2,2,0,type=3,zeroprec=200).ae(0)
+ assert f(1.5,3,0,type=3).ae(2.2239343475841951022*(1-1j))
+ # Standard case, degree 0
+ assert f(0,0,-1.5).ae(-0.8047189562170501873 + 1.5707963267948966192j)
+ assert f(0,0,-0.5).ae(-0.54930614433405484570)
+ assert f(0,0,0,zeroprec=200).ae(0)
+ assert f(0,0,0.5).ae(0.54930614433405484570)
+ assert f(0,0,1.5).ae(0.8047189562170501873 - 1.5707963267948966192j)
+ assert f(0,0,-1.5,type=3).ae(-0.80471895621705018730)
+ assert f(0,0,-0.5,type=3).ae(-0.5493061443340548457 - 1.5707963267948966192j)
+ assert f(0,0,0,type=3).ae(-1.5707963267948966192j)
+ assert f(0,0,0.5,type=3).ae(0.5493061443340548457 - 1.5707963267948966192j)
+ assert f(0,0,1.5,type=3).ae(0.80471895621705018730)
+ # Standard case, degree 1
+ assert f(1,0,-1.5).ae(0.2070784343255752810 - 2.3561944901923449288j)
+ assert f(1,0,-0.5).ae(-0.72534692783297257715)
+ assert f(1,0,0).ae(-1)
+ assert f(1,0,0.5).ae(-0.72534692783297257715)
+ assert f(1,0,1.5).ae(0.2070784343255752810 - 2.3561944901923449288j)
+ # Standard case, degree 2
+ assert f(2,0,-1.5).ae(-0.0635669991240192885 + 4.5160394395353277803j)
+ assert f(2,0,-0.5).ae(0.81866326804175685571)
+ assert f(2,0,0,zeroprec=200).ae(0)
+ assert f(2,0,0.5).ae(-0.81866326804175685571)
+ assert f(2,0,1.5).ae(0.0635669991240192885 - 4.5160394395353277803j)
+ # Misc orders and degrees
+ assert f(2,3,1.5,type=2).ae(-5.7243340223994616228j)
+ assert f(2,3,1.5,type=3).ae(-5.7243340223994616228)
+ assert f(2,3,0.5,type=2).ae(-12.316805742712016310)
+ assert f(2,3,0.5,type=3).ae(-12.316805742712016310j)
+ assert f(2,3,-1.5,type=2).ae(-5.7243340223994616228j)
+ assert f(2,3,-1.5,type=3).ae(5.7243340223994616228)
+ assert f(2,3,-0.5,type=2).ae(-12.316805742712016310)
+ assert f(2,3,-0.5,type=3).ae(-12.316805742712016310j)
+ assert f(2+3j, 3+4j, 0.5, type=3).ae(0.0016119404873235186807 - 0.0005885900510718119836j)
+ assert f(2+3j, 3+4j, -1.5, type=3).ae(0.008451400254138808670 + 0.020645193304593235298j)
+ assert f(-2.5,1,-1.5).ae(3.9553395527435335749j)
+ assert f(-2.5,1,-0.5).ae(1.9290561746445456908)
+ assert f(-2.5,1,0).ae(1.2708196271909686299)
+ assert f(-2.5,1,0.5).ae(-0.31584812990742202869)
+ assert f(-2.5,1,1.5).ae(-3.9553395527435335742 + 0.2993235655044701706j)
+ assert f(-2.5,1,-1.5,type=3).ae(0.29932356550447017254j)
+ assert f(-2.5,1,-0.5,type=3).ae(-0.3158481299074220287 - 1.9290561746445456908j)
+ assert f(-2.5,1,0,type=3).ae(1.2708196271909686292 - 1.2708196271909686299j)
+ assert f(-2.5,1,0.5,type=3).ae(1.9290561746445456907 + 0.3158481299074220287j)
+ assert f(-2.5,1,1.5,type=3).ae(-0.29932356550447017254)
+
+def test_agm():
+ mp.dps = 15
+ assert agm(0,0) == 0
+ assert agm(0,1) == 0
+ assert agm(1,1) == 1
+ assert agm(7,7) == 7
+ assert agm(j,j) == j
+ assert (1/agm(1,sqrt(2))).ae(0.834626841674073186)
+ assert agm(1,2).ae(1.4567910310469068692)
+ assert agm(1,3).ae(1.8636167832448965424)
+ assert agm(1,j).ae(0.599070117367796104+0.599070117367796104j)
+ assert agm(2) == agm(1,2)
+ assert agm(-3,4).ae(0.63468509766550907+1.3443087080896272j)
+
+def test_gammainc():
+ mp.dps = 15
+ assert gammainc(2,5).ae(6*exp(-5))
+ assert gammainc(2,0,5).ae(1-6*exp(-5))
+ assert gammainc(2,3,5).ae(-6*exp(-5)+4*exp(-3))
+ assert gammainc(-2.5,-0.5).ae(-0.9453087204829418812-5.3164237738936178621j)
+ assert gammainc(0,2,4).ae(0.045121158298212213088)
+ assert gammainc(0,3).ae(0.013048381094197037413)
+ assert gammainc(0,2+j,1-j).ae(0.00910653685850304839-0.22378752918074432574j)
+ assert gammainc(0,1-j).ae(0.00028162445198141833+0.17932453503935894015j)
+ assert gammainc(3,4,5,True).ae(0.11345128607046320253)
+ assert gammainc(3.5,0,inf).ae(gamma(3.5))
+ assert gammainc(-150.5,500).ae('6.9825435345798951153e-627')
+ assert gammainc(-150.5,800).ae('4.6885137549474089431e-788')
+ assert gammainc(-3.5, -20.5).ae(0.27008820585226911 - 1310.31447140574997636j)
+ assert gammainc(-3.5, -200.5).ae(0.27008820585226911 - 5.3264597096208368435e76j) # XXX real part
+ assert gammainc(0,0,2) == inf
+ assert gammainc(1,b=1).ae(0.6321205588285576784)
+ assert gammainc(3,2,2) == 0
+ assert gammainc(2,3+j,3-j).ae(-0.28135485191849314194j)
+ assert gammainc(4+0j,1).ae(5.8860710587430771455)
+ # GH issue #301
+ assert gammainc(-1,-1).ae(-0.8231640121031084799 + 3.1415926535897932385j)
+ assert gammainc(-2,-1).ae(1.7707229202810768576 - 1.5707963267948966192j)
+ assert gammainc(-3,-1).ae(-1.4963349162467073643 + 0.5235987755982988731j)
+ assert gammainc(-4,-1).ae(1.05365418617643814992 - 0.13089969389957471827j)
+ # Regularized upper gamma
+ assert isnan(gammainc(0, 0, regularized=True))
+ assert gammainc(-1, 0, regularized=True) == inf
+ assert gammainc(1, 0, regularized=True) == 1
+ assert gammainc(0, 5, regularized=True) == 0
+ assert gammainc(0, 2+3j, regularized=True) == 0
+ assert gammainc(0, 5000, regularized=True) == 0
+ assert gammainc(0, 10**30, regularized=True) == 0
+ assert gammainc(-1, 5, regularized=True) == 0
+ assert gammainc(-1, 5000, regularized=True) == 0
+ assert gammainc(-1, 10**30, regularized=True) == 0
+ assert gammainc(-1, -5, regularized=True) == 0
+ assert gammainc(-1, -5000, regularized=True) == 0
+ assert gammainc(-1, -10**30, regularized=True) == 0
+ assert gammainc(-1, 3+4j, regularized=True) == 0
+ assert gammainc(1, 5, regularized=True).ae(exp(-5))
+ assert gammainc(1, 5000, regularized=True).ae(exp(-5000))
+ assert gammainc(1, 10**30, regularized=True).ae(exp(-10**30))
+ assert gammainc(1, 3+4j, regularized=True).ae(exp(-3-4j))
+ assert gammainc(-1000000,2).ae('1.3669297209397347754e-301037', abs_eps=0, rel_eps=8*eps)
+ assert gammainc(-1000000,2,regularized=True) == 0
+ assert gammainc(-1000000,3+4j).ae('-1.322575609404222361e-698979 - 4.9274570591854533273e-698978j', abs_eps=0, rel_eps=8*eps)
+ assert gammainc(-1000000,3+4j,regularized=True) == 0
+ assert gammainc(2+3j, 4+5j, regularized=True).ae(0.085422013530993285774-0.052595379150390078503j)
+ assert gammainc(1000j, 1000j, regularized=True).ae(0.49702647628921131761 + 0.00297355675013575341j)
+ # Generalized
+ assert gammainc(3,4,2) == -gammainc(3,2,4)
+ assert gammainc(4, 2, 3).ae(1.2593494302978947396)
+ assert gammainc(4, 2, 3, regularized=True).ae(0.20989157171631578993)
+ assert gammainc(0, 2, 3).ae(0.035852129613864082155)
+ assert gammainc(0, 2, 3, regularized=True) == 0
+ assert gammainc(-1, 2, 3).ae(0.015219822548487616132)
+ assert gammainc(-1, 2, 3, regularized=True) == 0
+ assert gammainc(0, 2, 3).ae(0.035852129613864082155)
+ assert gammainc(0, 2, 3, regularized=True) == 0
+ # Should use upper gammas
+ assert gammainc(5, 10000, 12000).ae('1.1359381951461801687e-4327', abs_eps=0, rel_eps=8*eps)
+ # Should use lower gammas
+ assert gammainc(10000, 2, 3).ae('8.1244514125995785934e4765')
+ # GH issue 306
+ assert gammainc(3,-1-1j) == 0
+ assert gammainc(3,-1+1j) == 0
+ assert gammainc(2,-1) == 0
+ assert gammainc(2,-1+0j) == 0
+ assert gammainc(2+0j,-1) == 0
+
+def test_gammainc_expint_n():
+ # These tests are intended to check all cases of the low-level code
+ # for upper gamma and expint with small integer index.
+ # Need to cover positive/negative arguments; small/large/huge arguments
+ # for both positive and negative indices, as well as indices 0 and 1
+ # which may be special-cased
+ mp.dps = 15
+ assert expint(-3,3.5).ae(0.021456366563296693987)
+ assert expint(-2,3.5).ae(0.014966633183073309405)
+ assert expint(-1,3.5).ae(0.011092916359219041088)
+ assert expint(0,3.5).ae(0.0086278238349481430685)
+ assert expint(1,3.5).ae(0.0069701398575483929193)
+ assert expint(2,3.5).ae(0.0058018939208991255223)
+ assert expint(3,3.5).ae(0.0049453773495857807058)
+ assert expint(-3,-3.5).ae(-4.6618170604073311319)
+ assert expint(-2,-3.5).ae(-5.5996974157555515963)
+ assert expint(-1,-3.5).ae(-6.7582555017739415818)
+ assert expint(0,-3.5).ae(-9.4615577024835182145)
+ assert expint(1,-3.5).ae(-13.925353995152335292 - 3.1415926535897932385j)
+ assert expint(2,-3.5).ae(-15.62328702434085977 - 10.995574287564276335j)
+ assert expint(3,-3.5).ae(-10.783026313250347722 - 19.242255003237483586j)
+ assert expint(-3,350).ae(2.8614825451252838069e-155, abs_eps=0, rel_eps=8*eps)
+ assert expint(-2,350).ae(2.8532837224504675901e-155, abs_eps=0, rel_eps=8*eps)
+ assert expint(-1,350).ae(2.8451316155828634555e-155, abs_eps=0, rel_eps=8*eps)
+ assert expint(0,350).ae(2.8370258275042797989e-155, abs_eps=0, rel_eps=8*eps)
+ assert expint(1,350).ae(2.8289659656701459404e-155, abs_eps=0, rel_eps=8*eps)
+ assert expint(2,350).ae(2.8209516419468505006e-155, abs_eps=0, rel_eps=8*eps)
+ assert expint(3,350).ae(2.8129824725501272171e-155, abs_eps=0, rel_eps=8*eps)
+ assert expint(-3,-350).ae(-2.8528796154044839443e+149)
+ assert expint(-2,-350).ae(-2.8610072121701264351e+149)
+ assert expint(-1,-350).ae(-2.8691813842677537647e+149)
+ assert expint(0,-350).ae(-2.8774025343659421709e+149)
+ u = expint(1,-350)
+ assert u.ae(-2.8856710698020863568e+149)
+ assert u.imag.ae(-3.1415926535897932385)
+ u = expint(2,-350)
+ assert u.ae(-2.8939874026504650534e+149)
+ assert u.imag.ae(-1099.5574287564276335)
+ u = expint(3,-350)
+ assert u.ae(-2.9023519497915044349e+149)
+ assert u.imag.ae(-192422.55003237483586)
+ assert expint(-3,350000000000000000000000).ae('2.1592908471792544286e-152003068666138139677919', abs_eps=0, rel_eps=8*eps)
+ assert expint(-2,350000000000000000000000).ae('2.1592908471792544286e-152003068666138139677919', abs_eps=0, rel_eps=8*eps)
+ assert expint(-1,350000000000000000000000).ae('2.1592908471792544286e-152003068666138139677919', abs_eps=0, rel_eps=8*eps)
+ assert expint(0,350000000000000000000000).ae('2.1592908471792544286e-152003068666138139677919', abs_eps=0, rel_eps=8*eps)
+ assert expint(1,350000000000000000000000).ae('2.1592908471792544286e-152003068666138139677919', abs_eps=0, rel_eps=8*eps)
+ assert expint(2,350000000000000000000000).ae('2.1592908471792544286e-152003068666138139677919', abs_eps=0, rel_eps=8*eps)
+ assert expint(3,350000000000000000000000).ae('2.1592908471792544286e-152003068666138139677919', abs_eps=0, rel_eps=8*eps)
+ assert expint(-3,-350000000000000000000000).ae('-3.7805306852415755699e+152003068666138139677871')
+ assert expint(-2,-350000000000000000000000).ae('-3.7805306852415755699e+152003068666138139677871')
+ assert expint(-1,-350000000000000000000000).ae('-3.7805306852415755699e+152003068666138139677871')
+ assert expint(0,-350000000000000000000000).ae('-3.7805306852415755699e+152003068666138139677871')
+ u = expint(1,-350000000000000000000000)
+ assert u.ae('-3.7805306852415755699e+152003068666138139677871')
+ assert u.imag.ae(-3.1415926535897932385)
+ u = expint(2,-350000000000000000000000)
+ assert u.imag.ae(-1.0995574287564276335e+24)
+ assert u.ae('-3.7805306852415755699e+152003068666138139677871')
+ u = expint(3,-350000000000000000000000)
+ assert u.imag.ae(-1.9242255003237483586e+47)
+ assert u.ae('-3.7805306852415755699e+152003068666138139677871')
+ # Small case; no branch cut
+ assert gammainc(-3,3.5).ae(0.00010020262545203707109)
+ assert gammainc(-2,3.5).ae(0.00040370427343557393517)
+ assert gammainc(-1,3.5).ae(0.0016576839773997501492)
+ assert gammainc(0,3.5).ae(0.0069701398575483929193)
+ assert gammainc(1,3.5).ae(0.03019738342231850074)
+ assert gammainc(2,3.5).ae(0.13588822540043325333)
+ assert gammainc(3,3.5).ae(0.64169439772426814072)
+ # Small case; with branch cut
+ assert gammainc(-3,-3.5).ae(0.03595832954467563286 + 0.52359877559829887308j)
+ assert gammainc(-2,-3.5).ae(-0.88024704597962022221 - 1.5707963267948966192j)
+ assert gammainc(-1,-3.5).ae(4.4637962926688170771 + 3.1415926535897932385j)
+ assert gammainc(0,-3.5).ae(-13.925353995152335292 - 3.1415926535897932385j)
+ assert gammainc(1,-3.5).ae(33.115451958692313751)
+ assert gammainc(2,-3.5).ae(-82.788629896730784377)
+ assert gammainc(3,-3.5).ae(240.08702670051927469)
+ # Asymptotic case; no branch cut
+ assert gammainc(-3,350).ae(6.5424095113340358813e-163, abs_eps=0, rel_eps=8*eps)
+ assert gammainc(-2,350).ae(2.296312222489899769e-160, abs_eps=0, rel_eps=8*eps)
+ assert gammainc(-1,350).ae(8.059861834133858573e-158, abs_eps=0, rel_eps=8*eps)
+ assert gammainc(0,350).ae(2.8289659656701459404e-155, abs_eps=0, rel_eps=8*eps)
+ assert gammainc(1,350).ae(9.9295903962649792963e-153, abs_eps=0, rel_eps=8*eps)
+ assert gammainc(2,350).ae(3.485286229089007733e-150, abs_eps=0, rel_eps=8*eps)
+ assert gammainc(3,350).ae(1.2233453960006379793e-147, abs_eps=0, rel_eps=8*eps)
+ # Asymptotic case; branch cut
+ u = gammainc(-3,-350)
+ assert u.ae(6.7889565783842895085e+141)
+ assert u.imag.ae(0.52359877559829887308)
+ u = gammainc(-2,-350)
+ assert u.ae(-2.3692668977889832121e+144)
+ assert u.imag.ae(-1.5707963267948966192)
+ u = gammainc(-1,-350)
+ assert u.ae(8.2685354361441858669e+146)
+ assert u.imag.ae(3.1415926535897932385)
+ u = gammainc(0,-350)
+ assert u.ae(-2.8856710698020863568e+149)
+ assert u.imag.ae(-3.1415926535897932385)
+ u = gammainc(1,-350)
+ assert u.ae(1.0070908870280797598e+152)
+ assert u.imag == 0
+ u = gammainc(2,-350)
+ assert u.ae(-3.5147471957279983618e+154)
+ assert u.imag == 0
+ u = gammainc(3,-350)
+ assert u.ae(1.2266568422179417091e+157)
+ assert u.imag == 0
+ # Extreme asymptotic case
+ assert gammainc(-3,350000000000000000000000).ae('5.0362468738874738859e-152003068666138139677990', abs_eps=0, rel_eps=8*eps)
+ assert gammainc(-2,350000000000000000000000).ae('1.7626864058606158601e-152003068666138139677966', abs_eps=0, rel_eps=8*eps)
+ assert gammainc(-1,350000000000000000000000).ae('6.1694024205121555102e-152003068666138139677943', abs_eps=0, rel_eps=8*eps)
+ assert gammainc(0,350000000000000000000000).ae('2.1592908471792544286e-152003068666138139677919', abs_eps=0, rel_eps=8*eps)
+ assert gammainc(1,350000000000000000000000).ae('7.5575179651273905e-152003068666138139677896', abs_eps=0, rel_eps=8*eps)
+ assert gammainc(2,350000000000000000000000).ae('2.645131287794586675e-152003068666138139677872', abs_eps=0, rel_eps=8*eps)
+ assert gammainc(3,350000000000000000000000).ae('9.2579595072810533625e-152003068666138139677849', abs_eps=0, rel_eps=8*eps)
+ u = gammainc(-3,-350000000000000000000000)
+ assert u.ae('8.8175642804468234866e+152003068666138139677800')
+ assert u.imag.ae(0.52359877559829887308)
+ u = gammainc(-2,-350000000000000000000000)
+ assert u.ae('-3.0861474981563882203e+152003068666138139677824')
+ assert u.imag.ae(-1.5707963267948966192)
+ u = gammainc(-1,-350000000000000000000000)
+ assert u.ae('1.0801516243547358771e+152003068666138139677848')
+ assert u.imag.ae(3.1415926535897932385)
+ u = gammainc(0,-350000000000000000000000)
+ assert u.ae('-3.7805306852415755699e+152003068666138139677871')
+ assert u.imag.ae(-3.1415926535897932385)
+ assert gammainc(1,-350000000000000000000000).ae('1.3231857398345514495e+152003068666138139677895')
+ assert gammainc(2,-350000000000000000000000).ae('-4.6311500894209300731e+152003068666138139677918')
+ assert gammainc(3,-350000000000000000000000).ae('1.6209025312973255256e+152003068666138139677942')
+
+def test_incomplete_beta():
+ mp.dps = 15
+ assert betainc(-2,-3,0.5,0.75).ae(63.4305673311255413583969)
+ assert betainc(4.5,0.5+2j,2.5,6).ae(0.2628801146130621387903065 + 0.5162565234467020592855378j)
+ assert betainc(4,5,0,6).ae(90747.77142857142857142857)
+
+def test_erf():
+ mp.dps = 15
+ assert erf(0) == 0
+ assert erf(1).ae(0.84270079294971486934)
+ assert erf(3+4j).ae(-120.186991395079444098 - 27.750337293623902498j)
+ assert erf(-4-3j).ae(-0.99991066178539168236 + 0.00004972026054496604j)
+ assert erf(pi).ae(0.99999112385363235839)
+ assert erf(1j).ae(1.6504257587975428760j)
+ assert erf(-1j).ae(-1.6504257587975428760j)
+ assert isinstance(erf(1), mpf)
+ assert isinstance(erf(-1), mpf)
+ assert isinstance(erf(0), mpf)
+ assert isinstance(erf(0j), mpc)
+ assert erf(inf) == 1
+ assert erf(-inf) == -1
+ assert erfi(0) == 0
+ assert erfi(1/pi).ae(0.371682698493894314)
+ assert erfi(inf) == inf
+ assert erfi(-inf) == -inf
+ assert erf(1+0j) == erf(1)
+ assert erfc(1+0j) == erfc(1)
+ assert erf(0.2+0.5j).ae(1 - erfc(0.2+0.5j))
+ assert erfc(0) == 1
+ assert erfc(1).ae(1-erf(1))
+ assert erfc(-1).ae(1-erf(-1))
+ assert erfc(1/pi).ae(1-erf(1/pi))
+ assert erfc(-10) == 2
+ assert erfc(-1000000) == 2
+ assert erfc(-inf) == 2
+ assert erfc(inf) == 0
+ assert isnan(erfc(nan))
+ assert (erfc(10**4)*mpf(10)**43429453).ae('3.63998738656420')
+ assert erf(8+9j).ae(-1072004.2525062051158 + 364149.91954310255423j)
+ assert erfc(8+9j).ae(1072005.2525062051158 - 364149.91954310255423j)
+ assert erfc(-8-9j).ae(-1072003.2525062051158 + 364149.91954310255423j)
+ mp.dps = 50
+ # This one does not use the asymptotic series
+ assert (erfc(10)*10**45).ae('2.0884875837625447570007862949577886115608181193212')
+ # This one does
+ assert (erfc(50)*10**1088).ae('2.0709207788416560484484478751657887929322509209954')
+ mp.dps = 15
+ assert str(erfc(10**50)) == '3.66744826532555e-4342944819032518276511289189166050822943970058036665661144537831658646492088707747292249493384317534'
+ assert erfinv(0) == 0
+ assert erfinv(0.5).ae(0.47693627620446987338)
+ assert erfinv(-0.5).ae(-0.47693627620446987338)
+ assert erfinv(1) == inf
+ assert erfinv(-1) == -inf
+ assert erf(erfinv(0.95)).ae(0.95)
+ assert erf(erfinv(0.999999999995)).ae(0.999999999995)
+ assert erf(erfinv(-0.999999999995)).ae(-0.999999999995)
+ mp.dps = 50
+ assert erf(erfinv('0.99999999999999999999999999999995')).ae('0.99999999999999999999999999999995')
+ assert erf(erfinv('0.999999999999999999999999999999995')).ae('0.999999999999999999999999999999995')
+ assert erf(erfinv('-0.999999999999999999999999999999995')).ae('-0.999999999999999999999999999999995')
+ mp.dps = 15
+ # Complex asymptotic expansions
+ v = erfc(50j)
+ assert v.real == 1
+ assert v.imag.ae('-6.1481820666053078736e+1083')
+ assert erfc(-100+5j).ae(2)
+ assert (erfc(100+5j)*10**4335).ae(2.3973567853824133572 - 3.9339259530609420597j)
+ assert erfc(100+100j).ae(0.00065234366376857698698 - 0.0039357263629214118437j)
+
+def test_pdf():
+ mp.dps = 15
+ assert npdf(-inf) == 0
+ assert npdf(inf) == 0
+ assert npdf(5,0,2).ae(npdf(5+4,4,2))
+ assert quadts(lambda x: npdf(x,-0.5,0.8), [-inf, inf]) == 1
+ assert ncdf(0) == 0.5
+ assert ncdf(3,3) == 0.5
+ assert ncdf(-inf) == 0
+ assert ncdf(inf) == 1
+ assert ncdf(10) == 1
+ # Verify that this is computed accurately
+ assert (ncdf(-10)*10**24).ae(7.619853024160526)
+
+def test_lambertw():
+ mp.dps = 15
+ assert lambertw(0) == 0
+ assert lambertw(0+0j) == 0
+ assert lambertw(inf) == inf
+ assert isnan(lambertw(nan))
+ assert lambertw(inf,1).real == inf
+ assert lambertw(inf,1).imag.ae(2*pi)
+ assert lambertw(-inf,1).real == inf
+ assert lambertw(-inf,1).imag.ae(3*pi)
+ assert lambertw(0,-1) == -inf
+ assert lambertw(0,1) == -inf
+ assert lambertw(0,3) == -inf
+ assert lambertw(e).ae(1)
+ assert lambertw(1).ae(0.567143290409783873)
+ assert lambertw(-pi/2).ae(j*pi/2)
+ assert lambertw(-log(2)/2).ae(-log(2))
+ assert lambertw(0.25).ae(0.203888354702240164)
+ assert lambertw(-0.25).ae(-0.357402956181388903)
+ assert lambertw(-1./10000,0).ae(-0.000100010001500266719)
+ assert lambertw(-0.25,-1).ae(-2.15329236411034965)
+ assert lambertw(0.25,-1).ae(-3.00899800997004620-4.07652978899159763j)
+ assert lambertw(-0.25,-1).ae(-2.15329236411034965)
+ assert lambertw(0.25,1).ae(-3.00899800997004620+4.07652978899159763j)
+ assert lambertw(-0.25,1).ae(-3.48973228422959210+7.41405453009603664j)
+ assert lambertw(-4).ae(0.67881197132094523+1.91195078174339937j)
+ assert lambertw(-4,1).ae(-0.66743107129800988+7.76827456802783084j)
+ assert lambertw(-4,-1).ae(0.67881197132094523-1.91195078174339937j)
+ assert lambertw(1000).ae(5.24960285240159623)
+ assert lambertw(1000,1).ae(4.91492239981054535+5.44652615979447070j)
+ assert lambertw(1000,-1).ae(4.91492239981054535-5.44652615979447070j)
+ assert lambertw(1000,5).ae(3.5010625305312892+29.9614548941181328j)
+ assert lambertw(3+4j).ae(1.281561806123775878+0.533095222020971071j)
+ assert lambertw(-0.4+0.4j).ae(-0.10396515323290657+0.61899273315171632j)
+ assert lambertw(3+4j,1).ae(-0.11691092896595324+5.61888039871282334j)
+ assert lambertw(3+4j,-1).ae(0.25856740686699742-3.85211668616143559j)
+ assert lambertw(-0.5,-1).ae(-0.794023632344689368-0.770111750510379110j)
+ assert lambertw(-1./10000,1).ae(-11.82350837248724344+6.80546081842002101j)
+ assert lambertw(-1./10000,-1).ae(-11.6671145325663544)
+ assert lambertw(-1./10000,-2).ae(-11.82350837248724344-6.80546081842002101j)
+ assert lambertw(-1./100000,4).ae(-14.9186890769540539+26.1856750178782046j)
+ assert lambertw(-1./100000,5).ae(-15.0931437726379218666+32.5525721210262290086j)
+ assert lambertw((2+j)/10).ae(0.173704503762911669+0.071781336752835511j)
+ assert lambertw((2+j)/10,1).ae(-3.21746028349820063+4.56175438896292539j)
+ assert lambertw((2+j)/10,-1).ae(-3.03781405002993088-3.53946629633505737j)
+ assert lambertw((2+j)/10,4).ae(-4.6878509692773249+23.8313630697683291j)
+ assert lambertw(-(2+j)/10).ae(-0.226933772515757933-0.164986470020154580j)
+ assert lambertw(-(2+j)/10,1).ae(-2.43569517046110001+0.76974067544756289j)
+ assert lambertw(-(2+j)/10,-1).ae(-3.54858738151989450-6.91627921869943589j)
+ assert lambertw(-(2+j)/10,4).ae(-4.5500846928118151+20.6672982215434637j)
+ mp.dps = 50
+ assert lambertw(pi).ae('1.073658194796149172092178407024821347547745350410314531')
+ mp.dps = 15
+ # Former bug in generated branch
+ assert lambertw(-0.5+0.002j).ae(-0.78917138132659918344 + 0.76743539379990327749j)
+ assert lambertw(-0.5-0.002j).ae(-0.78917138132659918344 - 0.76743539379990327749j)
+ assert lambertw(-0.448+0.4j).ae(-0.11855133765652382241 + 0.66570534313583423116j)
+ assert lambertw(-0.448-0.4j).ae(-0.11855133765652382241 - 0.66570534313583423116j)
+ assert lambertw(-0.65475+0.0001j).ae(-0.61053421111385310898+1.0396534993944097723803j)
+ # Huge branch index
+ w = lambertw(1,10**20)
+ assert w.real.ae(-47.889578926290259164)
+ assert w.imag.ae(6.2831853071795864769e+20)
+
+def test_lambertw_hard():
+ def check(x,y):
+ y = convert(y)
+ type_ok = True
+ if isinstance(y, mpf):
+ type_ok = isinstance(x, mpf)
+ real_ok = abs(x.real-y.real) <= abs(y.real)*8*eps
+ imag_ok = abs(x.imag-y.imag) <= abs(y.imag)*8*eps
+ #print x, y, abs(x.real-y.real), abs(x.imag-y.imag)
+ return real_ok and imag_ok
+ # Evaluation near 0
+ mp.dps = 15
+ assert check(lambertw(1e-10), 9.999999999000000000e-11)
+ assert check(lambertw(-1e-10), -1.000000000100000000e-10)
+ assert check(lambertw(1e-10j), 9.999999999999999999733e-21 + 9.99999999999999999985e-11j)
+ assert check(lambertw(-1e-10j), 9.999999999999999999733e-21 - 9.99999999999999999985e-11j)
+ assert check(lambertw(1e-10,1), -26.303186778379041559 + 3.265093911703828397j)
+ assert check(lambertw(-1e-10,1), -26.326236166739163892 + 6.526183280686333315j)
+ assert check(lambertw(1e-10j,1), -26.312931726911421551 + 4.896366881798013421j)
+ assert check(lambertw(-1e-10j,1), -26.297238779529035066 + 1.632807161345576513j)
+ assert check(lambertw(1e-10,-1), -26.303186778379041559 - 3.265093911703828397j)
+ assert check(lambertw(-1e-10,-1), -26.295238819246925694)
+ assert check(lambertw(1e-10j,-1), -26.297238779529035028 - 1.6328071613455765135j)
+ assert check(lambertw(-1e-10j,-1), -26.312931726911421551 - 4.896366881798013421j)
+ # Test evaluation very close to the branch point -1/e
+ # on the -1, 0, and 1 branches
+ add = lambda x, y: fadd(x,y,exact=True)
+ sub = lambda x, y: fsub(x,y,exact=True)
+ addj = lambda x, y: fadd(x,fmul(y,1j,exact=True),exact=True)
+ subj = lambda x, y: fadd(x,fmul(y,-1j,exact=True),exact=True)
+ mp.dps = 1500
+ a = -1/e + 10*eps
+ d3 = mpf('1e-3')
+ d10 = mpf('1e-10')
+ d20 = mpf('1e-20')
+ d40 = mpf('1e-40')
+ d80 = mpf('1e-80')
+ d300 = mpf('1e-300')
+ d1000 = mpf('1e-1000')
+ mp.dps = 15
+ # ---- Branch 0 ----
+ # -1/e + eps
+ assert check(lambertw(add(a,d3)), -0.92802015005456704876)
+ assert check(lambertw(add(a,d10)), -0.99997668374140088071)
+ assert check(lambertw(add(a,d20)), -0.99999999976683560186)
+ assert lambertw(add(a,d40)) == -1
+ assert lambertw(add(a,d80)) == -1
+ assert lambertw(add(a,d300)) == -1
+ assert lambertw(add(a,d1000)) == -1
+ # -1/e - eps
+ assert check(lambertw(sub(a,d3)), -0.99819016149860989001+0.07367191188934638577j)
+ assert check(lambertw(sub(a,d10)), -0.9999999998187812114595992+0.0000233164398140346109194j)
+ assert check(lambertw(sub(a,d20)), -0.99999999999999999998187+2.331643981597124203344e-10j)
+ assert check(lambertw(sub(a,d40)), -1.0+2.33164398159712420336e-20j)
+ assert check(lambertw(sub(a,d80)), -1.0+2.33164398159712420336e-40j)
+ assert check(lambertw(sub(a,d300)), -1.0+2.33164398159712420336e-150j)
+ assert check(lambertw(sub(a,d1000)), mpc(-1,'2.33164398159712420336e-500'))
+ # -1/e + eps*j
+ assert check(lambertw(addj(a,d3)), -0.94790387486938526634+0.05036819639190132490j)
+ assert check(lambertw(addj(a,d10)), -0.9999835127872943680999899+0.0000164870314895821225256j)
+ assert check(lambertw(addj(a,d20)), -0.999999999835127872929987+1.64872127051890935830e-10j)
+ assert check(lambertw(addj(a,d40)), -0.9999999999999999999835+1.6487212707001281468305e-20j)
+ assert check(lambertw(addj(a,d80)), -1.0 + 1.64872127070012814684865e-40j)
+ assert check(lambertw(addj(a,d300)), -1.0 + 1.64872127070012814684865e-150j)
+ assert check(lambertw(addj(a,d1000)), mpc(-1.0,'1.64872127070012814684865e-500'))
+ # -1/e - eps*j
+ assert check(lambertw(subj(a,d3)), -0.94790387486938526634-0.05036819639190132490j)
+ assert check(lambertw(subj(a,d10)), -0.9999835127872943680999899-0.0000164870314895821225256j)
+ assert check(lambertw(subj(a,d20)), -0.999999999835127872929987-1.64872127051890935830e-10j)
+ assert check(lambertw(subj(a,d40)), -0.9999999999999999999835-1.6487212707001281468305e-20j)
+ assert check(lambertw(subj(a,d80)), -1.0 - 1.64872127070012814684865e-40j)
+ assert check(lambertw(subj(a,d300)), -1.0 - 1.64872127070012814684865e-150j)
+ assert check(lambertw(subj(a,d1000)), mpc(-1.0,'-1.64872127070012814684865e-500'))
+ # ---- Branch 1 ----
+ assert check(lambertw(addj(a,d3),1), -3.088501303219933378005990 + 7.458676867597474813950098j)
+ assert check(lambertw(addj(a,d80),1), -3.088843015613043855957087 + 7.461489285654254556906117j)
+ assert check(lambertw(addj(a,d300),1), -3.088843015613043855957087 + 7.461489285654254556906117j)
+ assert check(lambertw(addj(a,d1000),1), -3.088843015613043855957087 + 7.461489285654254556906117j)
+ assert check(lambertw(subj(a,d3),1), -1.0520914180450129534365906 + 0.0539925638125450525673175j)
+ assert check(lambertw(subj(a,d10),1), -1.0000164872127056318529390 + 0.000016487393927159250398333077j)
+ assert check(lambertw(subj(a,d20),1), -1.0000000001648721270700128 + 1.64872127088134693542628e-10j)
+ assert check(lambertw(subj(a,d40),1), -1.000000000000000000016487 + 1.64872127070012814686677e-20j)
+ assert check(lambertw(subj(a,d80),1), -1.0 + 1.64872127070012814684865e-40j)
+ assert check(lambertw(subj(a,d300),1), -1.0 + 1.64872127070012814684865e-150j)
+ assert check(lambertw(subj(a,d1000),1), mpc(-1.0, '1.64872127070012814684865e-500'))
+ # ---- Branch -1 ----
+ # -1/e + eps
+ assert check(lambertw(add(a,d3),-1), -1.075608941186624989414945)
+ assert check(lambertw(add(a,d10),-1), -1.000023316621036696460620)
+ assert check(lambertw(add(a,d20),-1), -1.000000000233164398177834)
+ assert lambertw(add(a,d40),-1) == -1
+ assert lambertw(add(a,d80),-1) == -1
+ assert lambertw(add(a,d300),-1) == -1
+ assert lambertw(add(a,d1000),-1) == -1
+ # -1/e - eps
+ assert check(lambertw(sub(a,d3),-1), -0.99819016149860989001-0.07367191188934638577j)
+ assert check(lambertw(sub(a,d10),-1), -0.9999999998187812114595992-0.0000233164398140346109194j)
+ assert check(lambertw(sub(a,d20),-1), -0.99999999999999999998187-2.331643981597124203344e-10j)
+ assert check(lambertw(sub(a,d40),-1), -1.0-2.33164398159712420336e-20j)
+ assert check(lambertw(sub(a,d80),-1), -1.0-2.33164398159712420336e-40j)
+ assert check(lambertw(sub(a,d300),-1), -1.0-2.33164398159712420336e-150j)
+ assert check(lambertw(sub(a,d1000),-1), mpc(-1,'-2.33164398159712420336e-500'))
+ # -1/e + eps*j
+ assert check(lambertw(addj(a,d3),-1), -1.0520914180450129534365906 - 0.0539925638125450525673175j)
+ assert check(lambertw(addj(a,d10),-1), -1.0000164872127056318529390 - 0.0000164873939271592503983j)
+ assert check(lambertw(addj(a,d20),-1), -1.0000000001648721270700 - 1.64872127088134693542628e-10j)
+ assert check(lambertw(addj(a,d40),-1), -1.00000000000000000001648 - 1.6487212707001281468667726e-20j)
+ assert check(lambertw(addj(a,d80),-1), -1.0 - 1.64872127070012814684865e-40j)
+ assert check(lambertw(addj(a,d300),-1), -1.0 - 1.64872127070012814684865e-150j)
+ assert check(lambertw(addj(a,d1000),-1), mpc(-1.0,'-1.64872127070012814684865e-500'))
+ # -1/e - eps*j
+ assert check(lambertw(subj(a,d3),-1), -3.088501303219933378005990-7.458676867597474813950098j)
+ assert check(lambertw(subj(a,d10),-1), -3.088843015579260686911033-7.461489285372968780020716j)
+ assert check(lambertw(subj(a,d20),-1), -3.088843015613043855953708-7.461489285654254556877988j)
+ assert check(lambertw(subj(a,d40),-1), -3.088843015613043855957087-7.461489285654254556906117j)
+ assert check(lambertw(subj(a,d80),-1), -3.088843015613043855957087 - 7.461489285654254556906117j)
+ assert check(lambertw(subj(a,d300),-1), -3.088843015613043855957087 - 7.461489285654254556906117j)
+ assert check(lambertw(subj(a,d1000),-1), -3.088843015613043855957087 - 7.461489285654254556906117j)
+ # One more case, testing higher precision
+ mp.dps = 500
+ x = -1/e + mpf('1e-13')
+ ans = "-0.99999926266961377166355784455394913638782494543377383"\
+ "744978844374498153493943725364881490261187530235150668593869563"\
+ "168276697689459394902153960200361935311512317183678882"
+ mp.dps = 15
+ assert lambertw(x).ae(ans)
+ mp.dps = 50
+ assert lambertw(x).ae(ans)
+ mp.dps = 150
+ assert lambertw(x).ae(ans)
+
+def test_meijerg():
+ mp.dps = 15
+ assert meijerg([[2,3],[1]],[[0.5,2],[3,4]], 2.5).ae(4.2181028074787439386)
+ assert meijerg([[],[1+j]],[[1],[1]], 3+4j).ae(271.46290321152464592 - 703.03330399954820169j)
+ assert meijerg([[0.25],[1]],[[0.5],[2]],0) == 0
+ assert meijerg([[0],[]],[[0,0,'1/3','2/3'], []], '2/27').ae(2.2019391389653314120)
+ # Verify 1/z series being used
+ assert meijerg([[-3],[-0.5]], [[-1],[-2.5]], -0.5).ae(-1.338096165935754898687431)
+ assert meijerg([[1-(-1)],[1-(-2.5)]], [[1-(-3)],[1-(-0.5)]], -2.0).ae(-1.338096165935754898687431)
+ assert meijerg([[-3],[-0.5]], [[-1],[-2.5]], -1).ae(-(pi+4)/(4*pi))
+ a = 2.5
+ b = 1.25
+ for z in [mpf(0.25), mpf(2)]:
+ x1 = hyp1f1(a,b,z)
+ x2 = gamma(b)/gamma(a)*meijerg([[1-a],[]],[[0],[1-b]],-z)
+ x3 = gamma(b)/gamma(a)*meijerg([[1-0],[1-(1-b)]],[[1-(1-a)],[]],-1/z)
+ assert x1.ae(x2)
+ assert x1.ae(x3)
+
+def test_appellf1():
+ mp.dps = 15
+ assert appellf1(2,-2,1,1,2,3).ae(-1.75)
+ assert appellf1(2,1,-2,1,2,3).ae(-8)
+ assert appellf1(2,1,-2,1,0.5,0.25).ae(1.5)
+ assert appellf1(-2,1,3,2,3,3).ae(19)
+ assert appellf1(1,2,3,4,0.5,0.125).ae( 1.53843285792549786518)
+
+def test_coulomb():
+ # Note: most tests are doctests
+ # Test for a bug:
+ mp.dps = 15
+ assert coulombg(mpc(-5,0),2,3).ae(20.087729487721430394)
+
+def test_hyper_param_accuracy():
+ mp.dps = 15
+ As = [n+1e-10 for n in range(-5,-1)]
+ Bs = [n+1e-10 for n in range(-12,-5)]
+ assert hyper(As,Bs,10).ae(-381757055858.652671927)
+ assert legenp(0.5, 100, 0.25).ae(-2.4124576567211311755e+144)
+ assert (hyp1f1(1000,1,-100)*10**24).ae(5.2589445437370169113)
+ assert (hyp2f1(10, -900, 10.5, 0.99)*10**24).ae(1.9185370579660768203)
+ assert (hyp2f1(1000,1.5,-3.5,-1.5)*10**385).ae(-2.7367529051334000764)
+ assert hyp2f1(-5, 10, 3, 0.5, zeroprec=500) == 0
+ assert (hyp1f1(-10000, 1000, 100)*10**424).ae(-3.1046080515824859974)
+ assert (hyp2f1(1000,1.5,-3.5,-0.75,maxterms=100000)*10**231).ae(-4.0534790813913998643)
+ assert legenp(2, 3, 0.25) == 0
+ pytest.raises(ValueError, lambda: hypercomb(lambda a: [([],[],[],[],[a],[-a],0.5)], [3]))
+ assert hypercomb(lambda a: [([],[],[],[],[a],[-a],0.5)], [3], infprec=200) == inf
+ assert meijerg([[],[]],[[0,0,0,0],[]],0.1).ae(1.5680822343832351418)
+ assert (besselk(400,400)*10**94).ae(1.4387057277018550583)
+ mp.dps = 5
+ (hyp1f1(-5000.5, 1500, 100)*10**185).ae(8.5185229673381935522)
+ (hyp1f1(-5000, 1500, 100)*10**185).ae(9.1501213424563944311)
+ mp.dps = 15
+ (hyp1f1(-5000.5, 1500, 100)*10**185).ae(8.5185229673381935522)
+ (hyp1f1(-5000, 1500, 100)*10**185).ae(9.1501213424563944311)
+ assert hyp0f1(fadd(-20,'1e-100',exact=True), 0.25).ae(1.85014429040102783e+49)
+ assert hyp0f1((-20*10**100+1, 10**100), 0.25).ae(1.85014429040102783e+49)
+
+def test_hypercomb_zero_pow():
+ # check that 0^0 = 1
+ assert hypercomb(lambda a: (([0],[a],[],[],[],[],0),), [0]) == 1
+ assert meijerg([[-1.5],[]],[[0],[-0.75]],0).ae(1.4464090846320771425)
+
+def test_spherharm():
+ mp.dps = 15
+ t = 0.5; r = 0.25
+ assert spherharm(0,0,t,r).ae(0.28209479177387814347)
+ assert spherharm(1,-1,t,r).ae(0.16048941205971996369 - 0.04097967481096344271j)
+ assert spherharm(1,0,t,r).ae(0.42878904414183579379)
+ assert spherharm(1,1,t,r).ae(-0.16048941205971996369 - 0.04097967481096344271j)
+ assert spherharm(2,-2,t,r).ae(0.077915886919031181734 - 0.042565643022253962264j)
+ assert spherharm(2,-1,t,r).ae(0.31493387233497459884 - 0.08041582001959297689j)
+ assert spherharm(2,0,t,r).ae(0.41330596756220761898)
+ assert spherharm(2,1,t,r).ae(-0.31493387233497459884 - 0.08041582001959297689j)
+ assert spherharm(2,2,t,r).ae(0.077915886919031181734 + 0.042565643022253962264j)
+ assert spherharm(3,-3,t,r).ae(0.033640236589690881646 - 0.031339125318637082197j)
+ assert spherharm(3,-2,t,r).ae(0.18091018743101461963 - 0.09883168583167010241j)
+ assert spherharm(3,-1,t,r).ae(0.42796713930907320351 - 0.10927795157064962317j)
+ assert spherharm(3,0,t,r).ae(0.27861659336351639787)
+ assert spherharm(3,1,t,r).ae(-0.42796713930907320351 - 0.10927795157064962317j)
+ assert spherharm(3,2,t,r).ae(0.18091018743101461963 + 0.09883168583167010241j)
+ assert spherharm(3,3,t,r).ae(-0.033640236589690881646 - 0.031339125318637082197j)
+ assert spherharm(0,-1,t,r) == 0
+ assert spherharm(0,-2,t,r) == 0
+ assert spherharm(0,1,t,r) == 0
+ assert spherharm(0,2,t,r) == 0
+ assert spherharm(1,2,t,r) == 0
+ assert spherharm(1,3,t,r) == 0
+ assert spherharm(1,-2,t,r) == 0
+ assert spherharm(1,-3,t,r) == 0
+ assert spherharm(2,3,t,r) == 0
+ assert spherharm(2,4,t,r) == 0
+ assert spherharm(2,-3,t,r) == 0
+ assert spherharm(2,-4,t,r) == 0
+ assert spherharm(3,4.5,0.5,0.25).ae(-22.831053442240790148 + 10.910526059510013757j)
+ assert spherharm(2+3j, 1-j, 1+j, 3+4j).ae(-2.6582752037810116935 - 1.0909214905642160211j)
+ assert spherharm(-6,2.5,t,r).ae(0.39383644983851448178 + 0.28414687085358299021j)
+ assert spherharm(-3.5, 3, 0.5, 0.25).ae(0.014516852987544698924 - 0.015582769591477628495j)
+ assert spherharm(-3, 3, 0.5, 0.25) == 0
+ assert spherharm(-6, 3, 0.5, 0.25).ae(-0.16544349818782275459 - 0.15412657723253924562j)
+ assert spherharm(-6, 1.5, 0.5, 0.25).ae(0.032208193499767402477 + 0.012678000924063664921j)
+ assert spherharm(3,0,0,1).ae(0.74635266518023078283)
+ assert spherharm(3,-2,0,1) == 0
+ assert spherharm(3,-2,1,1).ae(-0.16270707338254028971 - 0.35552144137546777097j)
+
+def test_qfunctions():
+ mp.dps = 15
+ assert qp(2,3,100).ae('2.7291482267247332183e2391')
+
+def test_issue_239():
+ mp.prec = 150
+ x = ldexp(2476979795053773,-52)
+ assert betainc(206, 385, 0, 0.55, 1).ae('0.99999999999999999999996570910644857895771110649954')
+ mp.dps = 15
+ pytest.raises(ValueError, lambda: hyp2f1(-5,5,0.5,0.5))
+
+# Extra stress testing for Bessel functions
+# Reference zeros generated with the aid of scipy.special
+# jn_zero, jnp_zero, yn_zero, ynp_zero
+
+V = 15
+M = 15
+
+jn_small_zeros = \
+[[2.4048255576957728,
+ 5.5200781102863106,
+ 8.6537279129110122,
+ 11.791534439014282,
+ 14.930917708487786,
+ 18.071063967910923,
+ 21.211636629879259,
+ 24.352471530749303,
+ 27.493479132040255,
+ 30.634606468431975,
+ 33.775820213573569,
+ 36.917098353664044,
+ 40.058425764628239,
+ 43.19979171317673,
+ 46.341188371661814],
+ [3.8317059702075123,
+ 7.0155866698156188,
+ 10.173468135062722,
+ 13.323691936314223,
+ 16.470630050877633,
+ 19.615858510468242,
+ 22.760084380592772,
+ 25.903672087618383,
+ 29.046828534916855,
+ 32.189679910974404,
+ 35.332307550083865,
+ 38.474766234771615,
+ 41.617094212814451,
+ 44.759318997652822,
+ 47.901460887185447],
+ [5.1356223018406826,
+ 8.4172441403998649,
+ 11.619841172149059,
+ 14.795951782351261,
+ 17.959819494987826,
+ 21.116997053021846,
+ 24.270112313573103,
+ 27.420573549984557,
+ 30.569204495516397,
+ 33.7165195092227,
+ 36.86285651128381,
+ 40.008446733478192,
+ 43.153453778371463,
+ 46.297996677236919,
+ 49.442164110416873],
+ [6.3801618959239835,
+ 9.7610231299816697,
+ 13.015200721698434,
+ 16.223466160318768,
+ 19.409415226435012,
+ 22.582729593104442,
+ 25.748166699294978,
+ 28.908350780921758,
+ 32.064852407097709,
+ 35.218670738610115,
+ 38.370472434756944,
+ 41.520719670406776,
+ 44.669743116617253,
+ 47.817785691533302,
+ 50.965029906205183],
+ [7.5883424345038044,
+ 11.064709488501185,
+ 14.37253667161759,
+ 17.615966049804833,
+ 20.826932956962388,
+ 24.01901952477111,
+ 27.199087765981251,
+ 30.371007667117247,
+ 33.537137711819223,
+ 36.699001128744649,
+ 39.857627302180889,
+ 43.01373772335443,
+ 46.167853512924375,
+ 49.320360686390272,
+ 52.471551398458023],
+ [8.771483815959954,
+ 12.338604197466944,
+ 15.700174079711671,
+ 18.980133875179921,
+ 22.217799896561268,
+ 25.430341154222704,
+ 28.626618307291138,
+ 31.811716724047763,
+ 34.988781294559295,
+ 38.159868561967132,
+ 41.326383254047406,
+ 44.489319123219673,
+ 47.649399806697054,
+ 50.80716520300633,
+ 53.963026558378149],
+ [9.9361095242176849,
+ 13.589290170541217,
+ 17.003819667816014,
+ 20.320789213566506,
+ 23.58608443558139,
+ 26.820151983411405,
+ 30.033722386570469,
+ 33.233041762847123,
+ 36.422019668258457,
+ 39.603239416075404,
+ 42.778481613199507,
+ 45.949015998042603,
+ 49.11577372476426,
+ 52.279453903601052,
+ 55.440592068853149],
+ [11.086370019245084,
+ 14.821268727013171,
+ 18.287582832481726,
+ 21.641541019848401,
+ 24.934927887673022,
+ 28.191188459483199,
+ 31.42279419226558,
+ 34.637089352069324,
+ 37.838717382853611,
+ 41.030773691585537,
+ 44.21540850526126,
+ 47.394165755570512,
+ 50.568184679795566,
+ 53.738325371963291,
+ 56.905249991978781],
+ [12.225092264004655,
+ 16.037774190887709,
+ 19.554536430997055,
+ 22.94517313187462,
+ 26.266814641176644,
+ 29.54565967099855,
+ 32.795800037341462,
+ 36.025615063869571,
+ 39.240447995178135,
+ 42.443887743273558,
+ 45.638444182199141,
+ 48.825930381553857,
+ 52.007691456686903,
+ 55.184747939289049,
+ 58.357889025269694],
+ [13.354300477435331,
+ 17.241220382489128,
+ 20.807047789264107,
+ 24.233885257750552,
+ 27.583748963573006,
+ 30.885378967696675,
+ 34.154377923855096,
+ 37.400099977156589,
+ 40.628553718964528,
+ 43.843801420337347,
+ 47.048700737654032,
+ 50.245326955305383,
+ 53.435227157042058,
+ 56.619580266508436,
+ 59.799301630960228],
+ [14.475500686554541,
+ 18.433463666966583,
+ 22.046985364697802,
+ 25.509450554182826,
+ 28.887375063530457,
+ 32.211856199712731,
+ 35.499909205373851,
+ 38.761807017881651,
+ 42.004190236671805,
+ 45.231574103535045,
+ 48.447151387269394,
+ 51.653251668165858,
+ 54.851619075963349,
+ 58.043587928232478,
+ 61.230197977292681],
+ [15.589847884455485,
+ 19.61596690396692,
+ 23.275853726263409,
+ 26.773322545509539,
+ 30.17906117878486,
+ 33.526364075588624,
+ 36.833571341894905,
+ 40.111823270954241,
+ 43.368360947521711,
+ 46.608132676274944,
+ 49.834653510396724,
+ 53.050498959135054,
+ 56.257604715114484,
+ 59.457456908388002,
+ 62.651217388202912],
+ [16.698249933848246,
+ 20.789906360078443,
+ 24.494885043881354,
+ 28.026709949973129,
+ 31.45996003531804,
+ 34.829986990290238,
+ 38.156377504681354,
+ 41.451092307939681,
+ 44.721943543191147,
+ 47.974293531269048,
+ 51.211967004101068,
+ 54.437776928325074,
+ 57.653844811906946,
+ 60.8618046824805,
+ 64.062937824850136],
+ [17.801435153282442,
+ 21.95624406783631,
+ 25.705103053924724,
+ 29.270630441874802,
+ 32.731053310978403,
+ 36.123657666448762,
+ 39.469206825243883,
+ 42.780439265447158,
+ 46.06571091157561,
+ 49.330780096443524,
+ 52.579769064383396,
+ 55.815719876305778,
+ 59.040934037249271,
+ 62.257189393731728,
+ 65.465883797232125],
+ [18.899997953174024,
+ 23.115778347252756,
+ 26.907368976182104,
+ 30.505950163896036,
+ 33.993184984781542,
+ 37.408185128639695,
+ 40.772827853501868,
+ 44.100590565798301,
+ 47.400347780543231,
+ 50.678236946479898,
+ 53.93866620912693,
+ 57.184898598119301,
+ 60.419409852130297,
+ 63.644117508962281,
+ 66.860533012260103]]
+
+jnp_small_zeros = \
+[[0.0,
+ 3.8317059702075123,
+ 7.0155866698156188,
+ 10.173468135062722,
+ 13.323691936314223,
+ 16.470630050877633,
+ 19.615858510468242,
+ 22.760084380592772,
+ 25.903672087618383,
+ 29.046828534916855,
+ 32.189679910974404,
+ 35.332307550083865,
+ 38.474766234771615,
+ 41.617094212814451,
+ 44.759318997652822],
+ [1.8411837813406593,
+ 5.3314427735250326,
+ 8.5363163663462858,
+ 11.706004902592064,
+ 14.863588633909033,
+ 18.015527862681804,
+ 21.16436985918879,
+ 24.311326857210776,
+ 27.457050571059246,
+ 30.601922972669094,
+ 33.746182898667383,
+ 36.889987409236811,
+ 40.033444053350675,
+ 43.176628965448822,
+ 46.319597561173912],
+ [3.0542369282271403,
+ 6.7061331941584591,
+ 9.9694678230875958,
+ 13.170370856016123,
+ 16.347522318321783,
+ 19.512912782488205,
+ 22.671581772477426,
+ 25.826037141785263,
+ 28.977672772993679,
+ 32.127327020443474,
+ 35.275535050674691,
+ 38.422654817555906,
+ 41.568934936074314,
+ 44.714553532819734,
+ 47.859641607992093],
+ [4.2011889412105285,
+ 8.0152365983759522,
+ 11.345924310743006,
+ 14.585848286167028,
+ 17.78874786606647,
+ 20.9724769365377,
+ 24.144897432909265,
+ 27.310057930204349,
+ 30.470268806290424,
+ 33.626949182796679,
+ 36.781020675464386,
+ 39.933108623659488,
+ 43.083652662375079,
+ 46.232971081836478,
+ 49.381300092370349],
+ [5.3175531260839944,
+ 9.2823962852416123,
+ 12.681908442638891,
+ 15.964107037731551,
+ 19.196028800048905,
+ 22.401032267689004,
+ 25.589759681386733,
+ 28.767836217666503,
+ 31.938539340972783,
+ 35.103916677346764,
+ 38.265316987088158,
+ 41.423666498500732,
+ 44.579623137359257,
+ 47.733667523865744,
+ 50.886159153182682],
+ [6.4156163757002403,
+ 10.519860873772308,
+ 13.9871886301403,
+ 17.312842487884625,
+ 20.575514521386888,
+ 23.803581476593863,
+ 27.01030789777772,
+ 30.20284907898166,
+ 33.385443901010121,
+ 36.560777686880356,
+ 39.730640230067416,
+ 42.896273163494417,
+ 46.058566273567043,
+ 49.218174614666636,
+ 52.375591529563596],
+ [7.501266144684147,
+ 11.734935953042708,
+ 15.268181461097873,
+ 18.637443009666202,
+ 21.931715017802236,
+ 25.183925599499626,
+ 28.409776362510085,
+ 31.617875716105035,
+ 34.81339298429743,
+ 37.999640897715301,
+ 41.178849474321413,
+ 44.352579199070217,
+ 47.521956905768113,
+ 50.687817781723741,
+ 53.85079463676896],
+ [8.5778364897140741,
+ 12.932386237089576,
+ 16.529365884366944,
+ 19.941853366527342,
+ 23.268052926457571,
+ 26.545032061823576,
+ 29.790748583196614,
+ 33.015178641375142,
+ 36.224380548787162,
+ 39.422274578939259,
+ 42.611522172286684,
+ 45.793999658055002,
+ 48.971070951900596,
+ 52.143752969301988,
+ 55.312820330403446],
+ [9.6474216519972168,
+ 14.115518907894618,
+ 17.774012366915256,
+ 21.229062622853124,
+ 24.587197486317681,
+ 27.889269427955092,
+ 31.155326556188325,
+ 34.39662855427218,
+ 37.620078044197086,
+ 40.830178681822041,
+ 44.030010337966153,
+ 47.221758471887113,
+ 50.407020967034367,
+ 53.586995435398319,
+ 56.762598475105272],
+ [10.711433970699945,
+ 15.28673766733295,
+ 19.004593537946053,
+ 22.501398726777283,
+ 25.891277276839136,
+ 29.218563499936081,
+ 32.505247352375523,
+ 35.763792928808799,
+ 39.001902811514218,
+ 42.224638430753279,
+ 45.435483097475542,
+ 48.636922645305525,
+ 51.830783925834728,
+ 55.01844255063594,
+ 58.200955824859509],
+ [11.770876674955582,
+ 16.447852748486498,
+ 20.223031412681701,
+ 23.760715860327448,
+ 27.182021527190532,
+ 30.534504754007074,
+ 33.841965775135715,
+ 37.118000423665604,
+ 40.371068905333891,
+ 43.606764901379516,
+ 46.828959446564562,
+ 50.040428970943456,
+ 53.243223214220535,
+ 56.438892058982552,
+ 59.628631306921512],
+ [12.826491228033465,
+ 17.600266557468326,
+ 21.430854238060294,
+ 25.008518704644261,
+ 28.460857279654847,
+ 31.838424458616998,
+ 35.166714427392629,
+ 38.460388720328256,
+ 41.728625562624312,
+ 44.977526250903469,
+ 48.211333836373288,
+ 51.433105171422278,
+ 54.645106240447105,
+ 57.849056857839799,
+ 61.046288512821078],
+ [13.878843069697276,
+ 18.745090916814406,
+ 22.629300302835503,
+ 26.246047773946584,
+ 29.72897816891134,
+ 33.131449953571661,
+ 36.480548302231658,
+ 39.791940718940855,
+ 43.075486800191012,
+ 46.337772104541405,
+ 49.583396417633095,
+ 52.815686826850452,
+ 56.037118687012179,
+ 59.249577075517968,
+ 62.454525995970462],
+ [14.928374492964716,
+ 19.88322436109951,
+ 23.81938909003628,
+ 27.474339750968247,
+ 30.987394331665278,
+ 34.414545662167183,
+ 37.784378506209499,
+ 41.113512376883377,
+ 44.412454519229281,
+ 47.688252845993366,
+ 50.945849245830813,
+ 54.188831071035124,
+ 57.419876154678179,
+ 60.641030026538746,
+ 63.853885828967512],
+ [15.975438807484321,
+ 21.015404934568315,
+ 25.001971500138194,
+ 28.694271223110755,
+ 32.236969407878118,
+ 35.688544091185301,
+ 39.078998185245057,
+ 42.425854432866141,
+ 45.740236776624833,
+ 49.029635055514276,
+ 52.299319390331728,
+ 55.553127779547459,
+ 58.793933759028134,
+ 62.02393848337554,
+ 65.244860767043859]]
+
+yn_small_zeros = \
+[[0.89357696627916752,
+ 3.9576784193148579,
+ 7.0860510603017727,
+ 10.222345043496417,
+ 13.361097473872763,
+ 16.500922441528091,
+ 19.64130970088794,
+ 22.782028047291559,
+ 25.922957653180923,
+ 29.064030252728398,
+ 32.205204116493281,
+ 35.346452305214321,
+ 38.487756653081537,
+ 41.629104466213808,
+ 44.770486607221993],
+ [2.197141326031017,
+ 5.4296810407941351,
+ 8.5960058683311689,
+ 11.749154830839881,
+ 14.897442128336725,
+ 18.043402276727856,
+ 21.188068934142213,
+ 24.331942571356912,
+ 27.475294980449224,
+ 30.618286491641115,
+ 33.761017796109326,
+ 36.90355531614295,
+ 40.045944640266876,
+ 43.188218097393211,
+ 46.330399250701687],
+ [3.3842417671495935,
+ 6.7938075132682675,
+ 10.023477979360038,
+ 13.209986710206416,
+ 16.378966558947457,
+ 19.539039990286384,
+ 22.69395593890929,
+ 25.845613720902269,
+ 28.995080395650151,
+ 32.143002257627551,
+ 35.289793869635804,
+ 38.435733485446343,
+ 41.581014867297885,
+ 44.725777117640461,
+ 47.870122696676504],
+ [4.5270246611496439,
+ 8.0975537628604907,
+ 11.396466739595867,
+ 14.623077742393873,
+ 17.81845523294552,
+ 20.997284754187761,
+ 24.166235758581828,
+ 27.328799850405162,
+ 30.486989604098659,
+ 33.642049384702463,
+ 36.794791029185579,
+ 39.945767226378749,
+ 43.095367507846703,
+ 46.2438744334407,
+ 49.391498015725107],
+ [5.6451478942208959,
+ 9.3616206152445429,
+ 12.730144474090465,
+ 15.999627085382479,
+ 19.22442895931681,
+ 22.424810599698521,
+ 25.610267054939328,
+ 28.785893657666548,
+ 31.954686680031668,
+ 35.118529525584828,
+ 38.278668089521758,
+ 41.435960629910073,
+ 44.591018225353424,
+ 47.744288086361052,
+ 50.896105199722123],
+ [6.7471838248710219,
+ 10.597176726782031,
+ 14.033804104911233,
+ 17.347086393228382,
+ 20.602899017175335,
+ 23.826536030287532,
+ 27.030134937138834,
+ 30.220335654231385,
+ 33.401105611047908,
+ 36.574972486670962,
+ 39.743627733020277,
+ 42.908248189569535,
+ 46.069679073215439,
+ 49.228543693445843,
+ 52.385312123112282],
+ [7.8377378223268716,
+ 11.811037107609447,
+ 15.313615118517857,
+ 18.670704965906724,
+ 21.958290897126571,
+ 25.206207715021249,
+ 28.429037095235496,
+ 31.634879502950644,
+ 34.828638524084437,
+ 38.013473399691765,
+ 41.19151880917741,
+ 44.364272633271975,
+ 47.53281875312084,
+ 50.697961822183806,
+ 53.860312300118388],
+ [8.919605734873789,
+ 13.007711435388313,
+ 16.573915129085334,
+ 19.974342312352426,
+ 23.293972585596648,
+ 26.5667563757203,
+ 29.809531451608321,
+ 33.031769327150685,
+ 36.239265816598239,
+ 39.435790312675323,
+ 42.623910919472727,
+ 45.805442883111651,
+ 48.981708325514764,
+ 52.153694518185572,
+ 55.322154420959698],
+ [9.9946283820824834,
+ 14.190361295800141,
+ 17.817887841179873,
+ 21.26093227125945,
+ 24.612576377421522,
+ 27.910524883974868,
+ 31.173701563441602,
+ 34.412862242025045,
+ 37.634648706110989,
+ 40.843415321050884,
+ 44.04214994542435,
+ 47.232978012841169,
+ 50.417456447370186,
+ 53.596753874948731,
+ 56.771765754432457],
+ [11.064090256031013,
+ 15.361301343575925,
+ 19.047949646361388,
+ 22.532765416313869,
+ 25.91620496332662,
+ 29.2394205079349,
+ 32.523270869465881,
+ 35.779715464475261,
+ 39.016196664616095,
+ 42.237627509803703,
+ 45.4474001519274,
+ 48.647941127433196,
+ 51.841036928216499,
+ 55.028034667184916,
+ 58.209970905250097],
+ [12.128927704415439,
+ 16.522284394784426,
+ 20.265984501212254,
+ 23.791669719454272,
+ 27.206568881574774,
+ 30.555020011020762,
+ 33.859683872746356,
+ 37.133649760307504,
+ 40.385117593813002,
+ 43.619533085646856,
+ 46.840676630553575,
+ 50.051265851897857,
+ 53.253310556711732,
+ 56.448332488918971,
+ 59.637507005589829],
+ [13.189846995683845,
+ 17.674674253171487,
+ 21.473493977824902,
+ 25.03913093040942,
+ 28.485081336558058,
+ 31.858644293774859,
+ 35.184165245422787,
+ 38.475796636190897,
+ 41.742455848758449,
+ 44.990096293791186,
+ 48.222870660068338,
+ 51.443777308699826,
+ 54.655042589416311,
+ 57.858358441436511,
+ 61.055036135780528],
+ [14.247395665073945,
+ 18.819555894710682,
+ 22.671697117872794,
+ 26.276375544903892,
+ 29.752925495549038,
+ 33.151412708998983,
+ 36.497763772987645,
+ 39.807134090704376,
+ 43.089121522203808,
+ 46.350163579538652,
+ 49.594769786270069,
+ 52.82620892320143,
+ 56.046916910756961,
+ 59.258751140598783,
+ 62.463155567737854],
+ [15.30200785858925,
+ 19.957808654258601,
+ 23.861599172945054,
+ 27.504429642227545,
+ 31.011103429019229,
+ 34.434283425782942,
+ 37.801385632318459,
+ 41.128514139788358,
+ 44.425913324440663,
+ 47.700482714581842,
+ 50.957073905278458,
+ 54.199216028087261,
+ 57.429547607017405,
+ 60.65008661807661,
+ 63.862406280068586],
+ [16.354034360047551,
+ 21.090156519983806,
+ 25.044040298785627,
+ 28.724161640881914,
+ 32.260472459522644,
+ 35.708083982611664,
+ 39.095820003878235,
+ 42.440684315990936,
+ 45.75353669045622,
+ 49.041718113283529,
+ 52.310408280968073,
+ 55.56338698149062,
+ 58.803488508906895,
+ 62.032886550960831,
+ 65.253280088312461]]
+
+ynp_small_zeros = \
+[[2.197141326031017,
+ 5.4296810407941351,
+ 8.5960058683311689,
+ 11.749154830839881,
+ 14.897442128336725,
+ 18.043402276727856,
+ 21.188068934142213,
+ 24.331942571356912,
+ 27.475294980449224,
+ 30.618286491641115,
+ 33.761017796109326,
+ 36.90355531614295,
+ 40.045944640266876,
+ 43.188218097393211,
+ 46.330399250701687],
+ [3.6830228565851777,
+ 6.9414999536541757,
+ 10.123404655436613,
+ 13.285758156782854,
+ 16.440058007293282,
+ 19.590241756629495,
+ 22.738034717396327,
+ 25.884314618788867,
+ 29.029575819372535,
+ 32.174118233366201,
+ 35.318134458192094,
+ 38.461753870997549,
+ 41.605066618873108,
+ 44.74813744908079,
+ 47.891014070791065],
+ [5.0025829314460639,
+ 8.3507247014130795,
+ 11.574195465217647,
+ 14.760909306207676,
+ 17.931285939466855,
+ 21.092894504412739,
+ 24.249231678519058,
+ 27.402145837145258,
+ 30.552708880564553,
+ 33.70158627151572,
+ 36.849213419846257,
+ 39.995887376143356,
+ 43.141817835750686,
+ 46.287157097544201,
+ 49.432018469138281],
+ [6.2536332084598136,
+ 9.6987879841487711,
+ 12.972409052292216,
+ 16.19044719506921,
+ 19.38238844973613,
+ 22.559791857764261,
+ 25.728213194724094,
+ 28.890678419054777,
+ 32.048984005266337,
+ 35.204266606440635,
+ 38.357281675961019,
+ 41.508551443818436,
+ 44.658448731963676,
+ 47.807246956681162,
+ 50.95515126455207],
+ [7.4649217367571329,
+ 11.005169149809189,
+ 14.3317235192331,
+ 17.58443601710272,
+ 20.801062338411128,
+ 23.997004122902644,
+ 27.179886689853435,
+ 30.353960608554323,
+ 33.521797098666792,
+ 36.685048382072301,
+ 39.844826969405863,
+ 43.001910515625288,
+ 46.15685955107263,
+ 49.310088614282257,
+ 52.461911043685864],
+ [8.6495562436971983,
+ 12.280868725807848,
+ 15.660799304540377,
+ 18.949739756016503,
+ 22.192841809428241,
+ 25.409072788867674,
+ 28.608039283077593,
+ 31.795195353138159,
+ 34.973890634255288,
+ 38.14630522169358,
+ 41.313923188794905,
+ 44.477791768537617,
+ 47.638672065035628,
+ 50.797131066967842,
+ 53.953600129601663],
+ [9.8147970120105779,
+ 13.532811875789828,
+ 16.965526446046053,
+ 20.291285512443867,
+ 23.56186260680065,
+ 26.799499736027237,
+ 30.015665481543419,
+ 33.216968050039509,
+ 36.407516858984748,
+ 39.590015243560459,
+ 42.766320595957378,
+ 45.937754257017323,
+ 49.105283450953203,
+ 52.269633324547373,
+ 55.431358715604255],
+ [10.965152105242974,
+ 14.765687379508912,
+ 18.250123150217555,
+ 21.612750053384621,
+ 24.911310600813573,
+ 28.171051927637585,
+ 31.40518108895689,
+ 34.621401012564177,
+ 37.824552065973114,
+ 41.017847386464902,
+ 44.203512240871601,
+ 47.3831408366063,
+ 50.557907466622796,
+ 53.728697478957026,
+ 56.896191727313342],
+ [12.103641941939539,
+ 15.982840905145284,
+ 19.517731005559611,
+ 22.916962141504605,
+ 26.243700855690533,
+ 29.525960140695407,
+ 32.778568197561124,
+ 36.010261572392516,
+ 39.226578757802172,
+ 42.43122493258747,
+ 45.626783824134354,
+ 48.815117837929515,
+ 51.997606404328863,
+ 55.175294723956816,
+ 58.348990221754937],
+ [13.232403808592215,
+ 17.186756572616758,
+ 20.770762917490496,
+ 24.206152448722253,
+ 27.561059462697153,
+ 30.866053571250639,
+ 34.137476603379774,
+ 37.385039772270268,
+ 40.614946085165892,
+ 43.831373184731238,
+ 47.037251786726299,
+ 50.234705848765229,
+ 53.425316228549359,
+ 56.610286079882087,
+ 59.790548623216652],
+ [14.35301374369987,
+ 18.379337301642568,
+ 22.011118775283494,
+ 25.482116178696707,
+ 28.865046588695164,
+ 32.192853922166294,
+ 35.483296655830277,
+ 38.747005493021857,
+ 41.990815194320955,
+ 45.219355876831731,
+ 48.435892856078888,
+ 51.642803925173029,
+ 54.84186659475857,
+ 58.034439083840155,
+ 61.221578745109862],
+ [15.466672066554263,
+ 19.562077985759503,
+ 23.240325531101082,
+ 26.746322986645901,
+ 30.157042415639891,
+ 33.507642948240263,
+ 36.817212798512775,
+ 40.097251300178642,
+ 43.355193847719752,
+ 46.596103410173672,
+ 49.823567279972794,
+ 53.040208868780832,
+ 56.247996968470062,
+ 59.448441365714251,
+ 62.642721301357187],
+ [16.574317035530872,
+ 20.73617763753932,
+ 24.459631728238804,
+ 27.999993668839644,
+ 31.438208790267783,
+ 34.811512070805535,
+ 38.140243708611251,
+ 41.436725143893739,
+ 44.708963264433333,
+ 47.962435051891027,
+ 51.201037321915983,
+ 54.427630745992975,
+ 57.644369734615238,
+ 60.852911791989989,
+ 64.054555435720397],
+ [17.676697936439624,
+ 21.9026148697762,
+ 25.670073356263225,
+ 29.244155124266438,
+ 32.709534477396028,
+ 36.105399554497548,
+ 39.453272918267025,
+ 42.766255701958017,
+ 46.052899215578358,
+ 49.319076602061401,
+ 52.568982147952547,
+ 55.805705507386287,
+ 59.031580956740466,
+ 62.248409689597653,
+ 65.457606670836759],
+ [18.774423978290318,
+ 23.06220035979272,
+ 26.872520985976736,
+ 30.479680663499762,
+ 33.971869047372436,
+ 37.390118854896324,
+ 40.757072537673599,
+ 44.086572292170345,
+ 47.387688809191869,
+ 50.66667461073936,
+ 53.928009929563275,
+ 57.175005343085052,
+ 60.410169281219877,
+ 63.635442539153021,
+ 66.85235358587768]]
+
+@pytest.mark.slow
+def test_bessel_zeros_extra():
+ mp.dps = 15
+ for v in range(V):
+ for m in range(1,M+1):
+ print(v, m, "of", V, M)
+ # Twice to test cache (if used)
+ assert besseljzero(v,m).ae(jn_small_zeros[v][m-1])
+ assert besseljzero(v,m).ae(jn_small_zeros[v][m-1])
+ assert besseljzero(v,m,1).ae(jnp_small_zeros[v][m-1])
+ assert besseljzero(v,m,1).ae(jnp_small_zeros[v][m-1])
+ assert besselyzero(v,m).ae(yn_small_zeros[v][m-1])
+ assert besselyzero(v,m).ae(yn_small_zeros[v][m-1])
+ assert besselyzero(v,m,1).ae(ynp_small_zeros[v][m-1])
+ assert besselyzero(v,m,1).ae(ynp_small_zeros[v][m-1])
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_gammazeta.py b/lib/python3.10/site-packages/mpmath/tests/test_gammazeta.py
new file mode 100644
index 0000000000000000000000000000000000000000..6a18a7964d746561dfd5f81177cd78ccc46d2a5d
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_gammazeta.py
@@ -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')
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_hp.py b/lib/python3.10/site-packages/mpmath/tests/test_hp.py
new file mode 100644
index 0000000000000000000000000000000000000000..9eba0af798f64ac3f8d464e2d3bf231567a48c9b
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_hp.py
@@ -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
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_identify.py b/lib/python3.10/site-packages/mpmath/tests/test_identify.py
new file mode 100644
index 0000000000000000000000000000000000000000..f75ab0bc4f04ecb614011e7f4599989465cab785
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_identify.py
@@ -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)'
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_interval.py b/lib/python3.10/site-packages/mpmath/tests/test_interval.py
new file mode 100644
index 0000000000000000000000000000000000000000..251fd8b7ddb00074e8ae27cce4a01d8f4f8fe151
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_interval.py
@@ -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)
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_levin.py b/lib/python3.10/site-packages/mpmath/tests/test_levin.py
new file mode 100644
index 0000000000000000000000000000000000000000..b14855df4de1a45da27080dcd239267842a4ac7a
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_levin.py
@@ -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
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_linalg.py b/lib/python3.10/site-packages/mpmath/tests/test_linalg.py
new file mode 100644
index 0000000000000000000000000000000000000000..14256a79f8953d3e4ef8b296258560d48204f547
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_linalg.py
@@ -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
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_matrices.py b/lib/python3.10/site-packages/mpmath/tests/test_matrices.py
new file mode 100644
index 0000000000000000000000000000000000000000..1547b90664dba66a98a7f026a04a4ed1aa1ed3b4
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_matrices.py
@@ -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)]])
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_mpmath.py b/lib/python3.10/site-packages/mpmath/tests/test_mpmath.py
new file mode 100644
index 0000000000000000000000000000000000000000..9f1fe36ae9b1b0feca4677eeb90396bfa7ed8f7a
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_mpmath.py
@@ -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)
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_ode.py b/lib/python3.10/site-packages/mpmath/tests/test_ode.py
new file mode 100644
index 0000000000000000000000000000000000000000..6b6dbffa79cfd4ca6dbf14f8591296ee48b16682
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_ode.py
@@ -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))
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_pickle.py b/lib/python3.10/site-packages/mpmath/tests/test_pickle.py
new file mode 100644
index 0000000000000000000000000000000000000000..c3d96e73a53603e0fa3f9525c5c0059725bdffb7
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_pickle.py
@@ -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)
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_power.py b/lib/python3.10/site-packages/mpmath/tests/test_power.py
new file mode 100644
index 0000000000000000000000000000000000000000..7a2447a62c36f9e02df79b9a40a8603f8a69b1d8
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_power.py
@@ -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< 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
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_quad.py b/lib/python3.10/site-packages/mpmath/tests/test_quad.py
new file mode 100644
index 0000000000000000000000000000000000000000..fc71c5f5ef9c0ecd876c988e7d033b321f065cdc
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_quad.py
@@ -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)
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_rootfinding.py b/lib/python3.10/site-packages/mpmath/tests/test_rootfinding.py
new file mode 100644
index 0000000000000000000000000000000000000000..7c3c06463682eb1fd60efeb75b809bbb932a241c
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_rootfinding.py
@@ -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)
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_special.py b/lib/python3.10/site-packages/mpmath/tests/test_special.py
new file mode 100644
index 0000000000000000000000000000000000000000..30825abd89ada00f937260cb51ef649546be7021
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_special.py
@@ -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
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_str.py b/lib/python3.10/site-packages/mpmath/tests/test_str.py
new file mode 100644
index 0000000000000000000000000000000000000000..569244f252c057ec1029b7efbd8b0ffbfbc47522
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_str.py
@@ -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]'''
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_summation.py b/lib/python3.10/site-packages/mpmath/tests/test_summation.py
new file mode 100644
index 0000000000000000000000000000000000000000..04ffd29f994e1e6310678eec292c0e03f2d6c725
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_summation.py
@@ -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
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_trig.py b/lib/python3.10/site-packages/mpmath/tests/test_trig.py
new file mode 100644
index 0000000000000000000000000000000000000000..c70a2a0ff4c44c784404ecdb15357d5b91a992d6
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_trig.py
@@ -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
diff --git a/lib/python3.10/site-packages/mpmath/tests/test_visualization.py b/lib/python3.10/site-packages/mpmath/tests/test_visualization.py
new file mode 100644
index 0000000000000000000000000000000000000000..81ffd05194322f00e4c75dc02bc862b383468bff
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/test_visualization.py
@@ -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)'
diff --git a/lib/python3.10/site-packages/mpmath/tests/torture.py b/lib/python3.10/site-packages/mpmath/tests/torture.py
new file mode 100644
index 0000000000000000000000000000000000000000..845d5c6d7d017e51e1ed9a8fe3106cfa32fd967f
--- /dev/null
+++ b/lib/python3.10/site-packages/mpmath/tests/torture.py
@@ -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)
diff --git a/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/__init__.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..959b2a81e8c27cf6e00a86258d4a11b3fb320dbb
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/__init__.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/dataframe.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/dataframe.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e9b054e88b526b751fd22204571d4400967db570
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/dataframe.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/expr.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/expr.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9a2c21f649755f39fc5a7ac1dd23caccc344e1b8
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/expr.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/group_by.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/group_by.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f6686aadbded96185796b1dbbab7b907c82c0dda
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/group_by.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/namespace.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/namespace.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3f8c46ba01cfd7cbc71a9226420218b20e636ac6
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/namespace.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/selectors.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/selectors.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..91ee5b430bd2e0bc6872c0bdddb054d9fec81160
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/selectors.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fb08c6c350391c54e895a756e777857cf7fc0ef6
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series_cat.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series_cat.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..cdf1632fce4f9e794d174f72df48c0837c726a44
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series_cat.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series_dt.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series_dt.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5d58b4d0310c0984cae40f4ff7cd9b20c213f92f
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series_dt.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series_list.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series_list.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fde60a3a15415cba9caae2653170d864b9be93c4
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series_list.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series_str.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series_str.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..22a93034a23e7756a8aa3f250002c85737e310e5
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series_str.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series_struct.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series_struct.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b57ed7e7269fd691f11eaf132f4736f9e5702e95
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/series_struct.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/typing.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/typing.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0e429ae20eb52c6fab02fe72a4dbb4b0c77d2209
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/typing.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/utils.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/utils.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6206f19e66558b3424595c126ae642d55e0f4bee
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_arrow/__pycache__/utils.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/__init__.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2fe6e64afc982635b7aa39b5f9bfcce1b6233398
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/__init__.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/any_namespace.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/any_namespace.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5a913d441489e61368ddce7d8c6acf8a1df8f12f
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/any_namespace.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/dataframe.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/dataframe.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..924166eabdb65085fc92e6bb3e3493f0c55474c5
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/dataframe.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/expr.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/expr.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c2156ddcd2310ca7542f472f14973846361b4c9b
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/expr.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/group_by.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/group_by.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..09c3092aef0bff9b21f7b8d6ec58b197154ba0ff
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/group_by.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/namespace.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/namespace.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..015d4562fb0715dba3338ebf93a9ded5c23c1027
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/namespace.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/selectors.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/selectors.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..24f6411d5ac98c639e54ec3e454d4a90daac9533
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/selectors.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/series.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/series.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d53f8f403c68ba7f58d866f248884a8e4f99f79b
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/series.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/typing.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/typing.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d5cb13736ede047abebe1eeab710fd241e97d5ab
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/typing.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/when_then.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/when_then.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ca175767cec3e4d3dffda2dfbcf7207f4528424a
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/when_then.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/window.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/window.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c8f46bcee275e4fa2727cc17a387a50ec7f89309
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_compliant/__pycache__/window.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_dask/__pycache__/__init__.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..af1096efbaac2f1194cae8e32279a1fa0072a1d7
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/__init__.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_dask/__pycache__/dataframe.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/dataframe.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1002eabb192e8cef484a2a45dcd4df3db79b0f85
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/dataframe.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_dask/__pycache__/expr.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/expr.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e4b35fbd2c1b98b6c0fa270fea2c41d1fb6bdd9e
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/expr.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_dask/__pycache__/expr_dt.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/expr_dt.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c9216c34b5fd9ab7fd82cb8e6b6ad2a05281bc1b
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/expr_dt.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_dask/__pycache__/expr_str.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/expr_str.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..09a0d6f2defac27a36c9ab2ea07d5355cdeaa6a6
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/expr_str.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_dask/__pycache__/group_by.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/group_by.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1b54b1e975de51389539a4d167ed46a2b302ffdf
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/group_by.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_dask/__pycache__/namespace.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/namespace.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3cf77fc3d5738cf465f0bc95202d83d6b1509d2b
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/namespace.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_dask/__pycache__/selectors.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/selectors.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..58a3522dede2f138a8cdfe99f7f9d9f7b656b466
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/selectors.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_dask/__pycache__/utils.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/utils.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0271c009ca994311241c389e994306349ed46c04
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_dask/__pycache__/utils.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/__init__.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e422194fe1f75c9f2caef25201ddb5283ae82c34
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/__init__.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/dataframe.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/dataframe.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fe1fc009ff9c1c501006fce28837d48c053ec788
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/dataframe.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/expr.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/expr.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..066588743757e1edec5083e39f0d55bbe029861d
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/expr.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/expr_dt.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/expr_dt.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1e112f607af4752292c65ed6a3a6ee8d8fa4a85d
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/expr_dt.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/expr_list.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/expr_list.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fcb7a218bb2a56d96537f90feef11ed7f5960d3e
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/expr_list.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/expr_str.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/expr_str.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..06bfc6ec2bd895fec4a1cfabe64bea4680e2375f
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/expr_str.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/expr_struct.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/expr_struct.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e435c25ee4e46c2f74f8666fa04fc326614c0092
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/expr_struct.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/group_by.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/group_by.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..deb4b61de314cb62ce6d88b4e30a88864b145f2f
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/group_by.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/namespace.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/namespace.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4214b25fabfbadfd5a2db45aba88defe916928c3
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/namespace.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/selectors.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/selectors.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..42e592358fcea2b6d8879166108ad451983c5df9
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/selectors.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/series.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/series.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..80110c60b931ff9e0d11cb4b9c5c2aff8dbccbc8
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/series.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/typing.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/typing.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..69f6cbaa71cb250ee353f5b9ffb8881d77f1852a
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/typing.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/utils.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/utils.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3992e9d3a4863057b52a28de4f6fd0ff32b25427
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_duckdb/__pycache__/utils.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_ibis/__pycache__/__init__.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_ibis/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f5a753b1e1794ff3a8c875fd7f9fd7ad5e12514d
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_ibis/__pycache__/__init__.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/_ibis/__pycache__/utils.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/_ibis/__pycache__/utils.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..16aac2d48297af1bc2695f92e973bfe2ba4e2242
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/_ibis/__pycache__/utils.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/stable/__pycache__/__init__.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/stable/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..19374782efe4415e7ed8c2c37864c6a69ac4fdf0
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/stable/__pycache__/__init__.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/stable/v1/__init__.py b/lib/python3.10/site-packages/narwhals/stable/v1/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..99680b903989a4821ec53498c9b45c7e3c433fa4
--- /dev/null
+++ b/lib/python3.10/site-packages/narwhals/stable/v1/__init__.py
@@ -0,0 +1,1389 @@
+from __future__ import annotations
+
+from functools import wraps
+from typing import TYPE_CHECKING, Any, Callable, Literal, cast, overload
+
+import narwhals as nw
+from narwhals import exceptions, functions as nw_f
+from narwhals._exceptions import issue_warning
+from narwhals._typing_compat import TypeVar, assert_never
+from narwhals._utils import (
+ Implementation,
+ Version,
+ deprecate_native_namespace,
+ generate_temporary_column_name,
+ inherit_doc,
+ is_ordered_categorical,
+ maybe_align_index,
+ maybe_convert_dtypes,
+ maybe_get_index,
+ maybe_reset_index,
+ maybe_set_index,
+ validate_strict_and_pass_though,
+)
+from narwhals.dataframe import DataFrame as NwDataFrame, LazyFrame as NwLazyFrame
+from narwhals.dependencies import get_polars
+from narwhals.exceptions import InvalidIntoExprError
+from narwhals.expr import Expr as NwExpr
+from narwhals.functions import _new_series_impl, concat, show_versions
+from narwhals.schema import Schema as NwSchema
+from narwhals.series import Series as NwSeries
+from narwhals.stable.v1 import dependencies, dtypes, selectors
+from narwhals.stable.v1.dtypes import (
+ Array,
+ Binary,
+ Boolean,
+ Categorical,
+ Date,
+ Datetime,
+ Decimal,
+ Duration,
+ Enum,
+ Field,
+ Float32,
+ Float64,
+ Int8,
+ Int16,
+ Int32,
+ Int64,
+ Int128,
+ List,
+ Object,
+ String,
+ Struct,
+ Time,
+ UInt8,
+ UInt16,
+ UInt32,
+ UInt64,
+ UInt128,
+ Unknown,
+)
+from narwhals.translate import _from_native_impl, get_native_namespace, to_py_scalar
+from narwhals.typing import IntoDataFrameT, IntoFrameT
+
+if TYPE_CHECKING:
+ from collections.abc import Iterable, Mapping, Sequence
+ from types import ModuleType
+
+ from typing_extensions import ParamSpec, Self
+
+ from narwhals._translate import IntoArrowTable
+ from narwhals.dataframe import MultiColSelector, MultiIndexSelector
+ from narwhals.dtypes import DType
+ from narwhals.typing import (
+ IntoDType,
+ IntoExpr,
+ IntoFrame,
+ IntoLazyFrameT,
+ IntoSeries,
+ NonNestedLiteral,
+ SingleColSelector,
+ SingleIndexSelector,
+ _1DArray,
+ _2DArray,
+ )
+
+ DataFrameT = TypeVar("DataFrameT", bound="DataFrame[Any]")
+ LazyFrameT = TypeVar("LazyFrameT", bound="LazyFrame[Any]")
+ SeriesT = TypeVar("SeriesT", bound="Series[Any]")
+ T = TypeVar("T", default=Any)
+ P = ParamSpec("P")
+ R = TypeVar("R")
+
+IntoSeriesT = TypeVar("IntoSeriesT", bound="IntoSeries", default=Any)
+
+
+class DataFrame(NwDataFrame[IntoDataFrameT]):
+ _version = Version.V1
+
+ @inherit_doc(NwDataFrame)
+ def __init__(self, df: Any, *, level: Literal["full", "lazy", "interchange"]) -> None:
+ assert df._version is Version.V1 # noqa: S101
+ super().__init__(df, level=level)
+
+ # We need to override any method which don't return Self so that type
+ # annotations are correct.
+
+ @classmethod
+ def from_arrow(
+ cls, native_frame: IntoArrowTable, *, backend: ModuleType | Implementation | str
+ ) -> DataFrame[Any]:
+ result = super().from_arrow(native_frame, backend=backend)
+ return cast("DataFrame[Any]", result)
+
+ @classmethod
+ def from_dict(
+ cls,
+ data: Mapping[str, Any],
+ schema: Mapping[str, DType] | Schema | None = None,
+ *,
+ backend: ModuleType | Implementation | str | None = None,
+ ) -> DataFrame[Any]:
+ result = super().from_dict(data, schema, backend=backend)
+ return cast("DataFrame[Any]", result)
+
+ @classmethod
+ def from_numpy(
+ cls,
+ data: _2DArray,
+ schema: Mapping[str, DType] | Schema | Sequence[str] | None = None,
+ *,
+ backend: ModuleType | Implementation | str,
+ ) -> DataFrame[Any]:
+ result = super().from_numpy(data, schema, backend=backend)
+ return cast("DataFrame[Any]", result)
+
+ @property
+ def _series(self) -> type[Series[Any]]:
+ return cast("type[Series[Any]]", Series)
+
+ @property
+ def _lazyframe(self) -> type[LazyFrame[Any]]:
+ return cast("type[LazyFrame[Any]]", LazyFrame)
+
+ @overload
+ def __getitem__(self, item: tuple[SingleIndexSelector, SingleColSelector]) -> Any: ...
+
+ @overload
+ def __getitem__( # type: ignore[overload-overlap]
+ self, item: str | tuple[MultiIndexSelector, SingleColSelector]
+ ) -> Series[Any]: ...
+
+ @overload
+ def __getitem__(
+ self,
+ item: (
+ SingleIndexSelector
+ | MultiIndexSelector
+ | MultiColSelector
+ | tuple[SingleIndexSelector, MultiColSelector]
+ | tuple[MultiIndexSelector, MultiColSelector]
+ ),
+ ) -> Self: ...
+ def __getitem__(
+ self,
+ item: (
+ SingleIndexSelector
+ | SingleColSelector
+ | MultiColSelector
+ | MultiIndexSelector
+ | tuple[SingleIndexSelector, SingleColSelector]
+ | tuple[SingleIndexSelector, MultiColSelector]
+ | tuple[MultiIndexSelector, SingleColSelector]
+ | tuple[MultiIndexSelector, MultiColSelector]
+ ),
+ ) -> Series[Any] | Self | Any:
+ return super().__getitem__(item)
+
+ def get_column(self, name: str) -> Series:
+ # Type checkers complain that `nw.Series` is not assignable to `nw.v1.stable.Series`.
+ # However the return type actually is `nw.v1.stable.Series`, check `tests/v1_test.py`.
+ return super().get_column(name) # type: ignore[return-value]
+
+ def lazy(
+ self, backend: ModuleType | Implementation | str | None = None
+ ) -> LazyFrame[Any]:
+ return _stableify(super().lazy(backend=backend))
+
+ @overload # type: ignore[override]
+ def to_dict(self, *, as_series: Literal[True] = ...) -> dict[str, Series[Any]]: ...
+ @overload
+ def to_dict(self, *, as_series: Literal[False]) -> dict[str, list[Any]]: ...
+ @overload
+ def to_dict(
+ self, *, as_series: bool
+ ) -> dict[str, Series[Any]] | dict[str, list[Any]]: ...
+ def to_dict(
+ self, *, as_series: bool = True
+ ) -> dict[str, Series[Any]] | dict[str, list[Any]]:
+ # Type checkers complain that `nw.Series` is not assignable to `nw.v1.stable.Series`.
+ # However the return type actually is `nw.v1.stable.Series`, check `tests/v1_test.py::test_to_dict_as_series`.
+ return super().to_dict(as_series=as_series) # type: ignore[return-value]
+
+ def is_duplicated(self) -> Series[Any]:
+ return _stableify(super().is_duplicated())
+
+ def is_unique(self) -> Series[Any]:
+ return _stableify(super().is_unique())
+
+ def _l1_norm(self) -> Self:
+ # Private, just used to test the stable API.
+ return self.select(all()._l1_norm())
+
+
+class LazyFrame(NwLazyFrame[IntoFrameT]):
+ @inherit_doc(NwLazyFrame)
+ def __init__(self, df: Any, *, level: Literal["full", "lazy", "interchange"]) -> None:
+ assert df._version is Version.V1 # noqa: S101
+ super().__init__(df, level=level)
+
+ @property
+ def _dataframe(self) -> type[DataFrame[Any]]:
+ return DataFrame
+
+ def _extract_compliant(self, arg: Any) -> Any:
+ # After v1, we raise when passing order-dependent or length-changing
+ # expressions to LazyFrame
+ from narwhals.dataframe import BaseFrame
+ from narwhals.expr import Expr
+ from narwhals.series import Series
+
+ if isinstance(arg, BaseFrame):
+ return arg._compliant_frame
+ if isinstance(arg, Series): # pragma: no cover
+ msg = "Mixing Series with LazyFrame is not supported."
+ raise TypeError(msg)
+ if isinstance(arg, Expr):
+ # After stable.v1, we raise for order-dependent exprs or filtrations
+ return arg._to_compliant_expr(self.__narwhals_namespace__())
+ if isinstance(arg, str):
+ plx = self.__narwhals_namespace__()
+ return plx.col(arg)
+ if get_polars() is not None and "polars" in str(type(arg)): # pragma: no cover
+ msg = (
+ f"Expected Narwhals object, got: {type(arg)}.\n\n"
+ "Perhaps you:\n"
+ "- Forgot a `nw.from_native` somewhere?\n"
+ "- Used `pl.col` instead of `nw.col`?"
+ )
+ raise TypeError(msg)
+ raise InvalidIntoExprError.from_invalid_type(type(arg))
+
+ def collect(
+ self, backend: ModuleType | Implementation | str | None = None, **kwargs: Any
+ ) -> DataFrame[Any]:
+ return _stableify(super().collect(backend=backend, **kwargs))
+
+ def _l1_norm(self) -> Self:
+ # Private, just used to test the stable API.
+ return self.select(all()._l1_norm())
+
+ def tail(self, n: int = 5) -> Self:
+ r"""Get the last `n` rows."""
+ return super().tail(n)
+
+ def gather_every(self, n: int, offset: int = 0) -> Self:
+ r"""Take every nth row in the DataFrame and return as a new DataFrame.
+
+ Arguments:
+ n: Gather every *n*-th row.
+ offset: Starting index.
+ """
+ return self._with_compliant(
+ self._compliant_frame.gather_every(n=n, offset=offset) # type: ignore[attr-defined]
+ )
+
+ def with_row_index(
+ self, name: str = "index", *, order_by: str | Sequence[str] | None = None
+ ) -> Self:
+ order_by_ = [order_by] if isinstance(order_by, str) else order_by
+ return self._with_compliant(
+ self._compliant_frame.with_row_index(
+ name=name,
+ order_by=order_by_, # type: ignore[arg-type]
+ )
+ )
+
+
+class Series(NwSeries[IntoSeriesT]):
+ @inherit_doc(NwSeries)
+ def __init__(
+ self, series: Any, *, level: Literal["full", "lazy", "interchange"]
+ ) -> None:
+ assert series._version is Version.V1 # noqa: S101
+ super().__init__(series, level=level)
+
+ # We need to override any method which don't return Self so that type
+ # annotations are correct.
+
+ @property
+ def _dataframe(self) -> type[DataFrame[Any]]:
+ return DataFrame
+
+ def to_frame(self) -> DataFrame[Any]:
+ return _stableify(super().to_frame())
+
+ def value_counts(
+ self,
+ *,
+ sort: bool = False,
+ parallel: bool = False,
+ name: str | None = None,
+ normalize: bool = False,
+ ) -> DataFrame[Any]:
+ return _stableify(
+ super().value_counts(
+ sort=sort, parallel=parallel, name=name, normalize=normalize
+ )
+ )
+
+ def hist(
+ self,
+ bins: list[float] | None = None,
+ *,
+ bin_count: int | None = None,
+ include_breakpoint: bool = True,
+ ) -> DataFrame[Any]:
+ from narwhals.exceptions import NarwhalsUnstableWarning
+
+ msg = (
+ "`Series.hist` is being called from the stable API although considered "
+ "an unstable feature."
+ )
+ issue_warning(msg, NarwhalsUnstableWarning)
+ return _stableify(
+ super().hist(
+ bins=bins, bin_count=bin_count, include_breakpoint=include_breakpoint
+ )
+ )
+
+
+class Expr(NwExpr):
+ def _l1_norm(self) -> Self:
+ return super()._taxicab_norm()
+
+ def head(self, n: int = 10) -> Self:
+ r"""Get the first `n` rows."""
+ return self._with_orderable_filtration(
+ lambda plx: self._to_compliant_expr(plx).head(n) # type: ignore[attr-defined]
+ )
+
+ def tail(self, n: int = 10) -> Self:
+ r"""Get the last `n` rows."""
+ return self._with_orderable_filtration(
+ lambda plx: self._to_compliant_expr(plx).tail(n) # type: ignore[attr-defined]
+ )
+
+ def gather_every(self, n: int, offset: int = 0) -> Self:
+ r"""Take every nth value in the Series and return as new Series.
+
+ Arguments:
+ n: Gather every *n*-th row.
+ offset: Starting index.
+ """
+ return self._with_orderable_filtration(
+ lambda plx: self._to_compliant_expr(plx).gather_every(n=n, offset=offset) # type: ignore[attr-defined]
+ )
+
+ def unique(self, *, maintain_order: bool | None = None) -> Self:
+ """Return unique values of this expression."""
+ if maintain_order is not None:
+ msg = (
+ "`maintain_order` has no effect and is only kept around for backwards-compatibility. "
+ "You can safely remove this argument."
+ )
+ issue_warning(msg, UserWarning)
+ return self._with_filtration(lambda plx: self._to_compliant_expr(plx).unique())
+
+ def sort(self, *, descending: bool = False, nulls_last: bool = False) -> Self:
+ """Sort this column. Place null values first."""
+ return self._with_window(
+ lambda plx: self._to_compliant_expr(plx).sort( # type: ignore[attr-defined]
+ descending=descending, nulls_last=nulls_last
+ )
+ )
+
+ def arg_max(self) -> Self:
+ """Returns the index of the maximum value."""
+ return self._with_orderable_aggregation(
+ lambda plx: self._to_compliant_expr(plx).arg_max() # type: ignore[attr-defined]
+ )
+
+ def arg_min(self) -> Self:
+ """Returns the index of the minimum value."""
+ return self._with_orderable_aggregation(
+ lambda plx: self._to_compliant_expr(plx).arg_min() # type: ignore[attr-defined]
+ )
+
+ def arg_true(self) -> Self:
+ """Find elements where boolean expression is True."""
+ return self._with_orderable_filtration(
+ lambda plx: self._to_compliant_expr(plx).arg_true() # type: ignore[attr-defined]
+ )
+
+ def sample(
+ self,
+ n: int | None = None,
+ *,
+ fraction: float | None = None,
+ with_replacement: bool = False,
+ seed: int | None = None,
+ ) -> Self:
+ """Sample randomly from this expression.
+
+ Arguments:
+ n: Number of items to return. Cannot be used with fraction.
+ fraction: Fraction of items to return. Cannot be used with n.
+ with_replacement: Allow values to be sampled more than once.
+ seed: Seed for the random number generator. If set to None (default), a random
+ seed is generated for each sample operation.
+
+ Returns:
+ A new expression.
+ """
+ return self._with_filtration(
+ lambda plx: self._to_compliant_expr(plx).sample( # type: ignore[attr-defined]
+ n, fraction=fraction, with_replacement=with_replacement, seed=seed
+ )
+ )
+
+
+class Schema(NwSchema):
+ _version = Version.V1
+
+ @inherit_doc(NwSchema)
+ def __init__(
+ self, schema: Mapping[str, DType] | Iterable[tuple[str, DType]] | None = None
+ ) -> None:
+ super().__init__(schema)
+
+
+@overload
+def _stableify(obj: NwDataFrame[IntoFrameT]) -> DataFrame[IntoFrameT]: ...
+@overload
+def _stableify(obj: NwLazyFrame[IntoFrameT]) -> LazyFrame[IntoFrameT]: ...
+@overload
+def _stableify(obj: NwSeries[IntoSeriesT]) -> Series[IntoSeriesT]: ...
+@overload
+def _stableify(obj: NwExpr) -> Expr: ...
+
+
+def _stableify(
+ obj: NwDataFrame[IntoFrameT]
+ | NwLazyFrame[IntoFrameT]
+ | NwSeries[IntoSeriesT]
+ | NwExpr,
+) -> DataFrame[IntoFrameT] | LazyFrame[IntoFrameT] | Series[IntoSeriesT] | Expr:
+ if isinstance(obj, NwDataFrame):
+ return DataFrame(obj._compliant_frame._with_version(Version.V1), level=obj._level)
+ if isinstance(obj, NwLazyFrame):
+ return LazyFrame(obj._compliant_frame._with_version(Version.V1), level=obj._level)
+ if isinstance(obj, NwSeries):
+ return Series(obj._compliant_series._with_version(Version.V1), level=obj._level)
+ if isinstance(obj, NwExpr):
+ return Expr(obj._to_compliant_expr, obj._metadata)
+ assert_never(obj)
+
+
+@overload
+def from_native(native_object: SeriesT, **kwds: Any) -> SeriesT: ...
+
+
+@overload
+def from_native(native_object: DataFrameT, **kwds: Any) -> DataFrameT: ...
+
+
+@overload
+def from_native(native_object: LazyFrameT, **kwds: Any) -> LazyFrameT: ...
+
+
+@overload
+def from_native(
+ native_object: DataFrameT | LazyFrameT, **kwds: Any
+) -> DataFrameT | LazyFrameT: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT | IntoSeriesT,
+ *,
+ strict: Literal[False],
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[True],
+ series_only: Literal[False] = ...,
+ allow_series: Literal[True],
+) -> DataFrame[IntoDataFrameT] | Series[IntoSeriesT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT | IntoSeriesT,
+ *,
+ strict: Literal[False],
+ eager_only: Literal[True],
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: Literal[True],
+) -> DataFrame[IntoDataFrameT] | Series[IntoSeriesT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT,
+ *,
+ strict: Literal[False],
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[True],
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> DataFrame[IntoDataFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: T,
+ *,
+ strict: Literal[False],
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[True],
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> T: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT,
+ *,
+ strict: Literal[False],
+ eager_only: Literal[True],
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> DataFrame[IntoDataFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: T,
+ *,
+ strict: Literal[False],
+ eager_only: Literal[True],
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> T: ...
+
+
+@overload
+def from_native(
+ native_object: IntoFrameT | IntoSeriesT,
+ *,
+ strict: Literal[False],
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: Literal[True],
+) -> DataFrame[IntoFrameT] | LazyFrame[IntoFrameT] | Series[IntoSeriesT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoSeriesT,
+ *,
+ strict: Literal[False],
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[True],
+ allow_series: None = ...,
+) -> Series[IntoSeriesT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoFrameT,
+ *,
+ strict: Literal[False],
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> DataFrame[IntoFrameT] | LazyFrame[IntoFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: T,
+ *,
+ strict: Literal[False],
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> T: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT,
+ *,
+ strict: Literal[True] = ...,
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[True],
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> DataFrame[IntoDataFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT,
+ *,
+ strict: Literal[True] = ...,
+ eager_only: Literal[True],
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> DataFrame[IntoDataFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoFrame | IntoSeries,
+ *,
+ strict: Literal[True] = ...,
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: Literal[True],
+) -> DataFrame[Any] | LazyFrame[Any] | Series[Any]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoSeriesT,
+ *,
+ strict: Literal[True] = ...,
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[True],
+ allow_series: None = ...,
+) -> Series[IntoSeriesT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoLazyFrameT,
+ *,
+ strict: Literal[True] = ...,
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> LazyFrame[IntoLazyFrameT]: ...
+
+
+# NOTE: `pl.LazyFrame` originally matched here
+@overload
+def from_native(
+ native_object: IntoFrameT,
+ *,
+ strict: Literal[True] = ...,
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> DataFrame[IntoFrameT] | LazyFrame[IntoFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT | IntoSeries,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[True],
+ series_only: Literal[False] = ...,
+ allow_series: Literal[True],
+) -> DataFrame[IntoDataFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT | IntoSeriesT,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[True],
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: Literal[True],
+) -> DataFrame[IntoDataFrameT] | Series[IntoSeriesT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[True],
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> DataFrame[IntoDataFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: T,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[True],
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> T: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[True],
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> DataFrame[IntoDataFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: T,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[True],
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> T: ...
+
+
+@overload
+def from_native(
+ native_object: IntoFrameT | IntoSeriesT,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: Literal[True],
+) -> DataFrame[IntoFrameT] | LazyFrame[IntoFrameT] | Series[IntoSeriesT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoSeriesT,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[True],
+ allow_series: None = ...,
+) -> Series[IntoSeriesT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoFrameT,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> DataFrame[IntoFrameT] | LazyFrame[IntoFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: T,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> T: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT,
+ *,
+ pass_through: Literal[False] = ...,
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[True],
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> DataFrame[IntoDataFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT,
+ *,
+ pass_through: Literal[False] = ...,
+ eager_only: Literal[True],
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> DataFrame[IntoDataFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoFrame | IntoSeries,
+ *,
+ pass_through: Literal[False] = ...,
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: Literal[True],
+) -> DataFrame[Any] | LazyFrame[Any] | Series[Any]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoSeriesT,
+ *,
+ pass_through: Literal[False] = ...,
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[True],
+ allow_series: None = ...,
+) -> Series[IntoSeriesT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoFrameT,
+ *,
+ pass_through: Literal[False] = ...,
+ eager_only: Literal[False] = ...,
+ eager_or_interchange_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> DataFrame[IntoFrameT] | LazyFrame[IntoFrameT]: ...
+
+
+# All params passed in as variables
+@overload
+def from_native(
+ native_object: Any,
+ *,
+ pass_through: bool,
+ eager_only: bool,
+ eager_or_interchange_only: bool = False,
+ series_only: bool,
+ allow_series: bool | None,
+) -> Any: ...
+
+
+def from_native(
+ native_object: IntoFrameT | IntoFrame | IntoSeriesT | IntoSeries | T,
+ *,
+ strict: bool | None = None,
+ pass_through: bool | None = None,
+ eager_only: bool = False,
+ eager_or_interchange_only: bool = False,
+ series_only: bool = False,
+ allow_series: bool | None = None,
+ **kwds: Any,
+) -> LazyFrame[IntoFrameT] | DataFrame[IntoFrameT] | Series[IntoSeriesT] | T:
+ """Convert `native_object` to Narwhals Dataframe, Lazyframe, or Series.
+
+ See `narwhals.from_native` for full docstring. Note that `native_namespace` is
+ an is the same as `backend` but only accepts module types - for new code, we
+ recommend using `backend`, as that's available beyond just `narwhals.stable.v1`.
+ """
+ # Early returns
+ if isinstance(native_object, (DataFrame, LazyFrame)) and not series_only:
+ return native_object
+ if isinstance(native_object, Series) and (series_only or allow_series):
+ return native_object
+
+ pass_through = validate_strict_and_pass_though(
+ strict, pass_through, pass_through_default=False
+ )
+ if kwds:
+ msg = f"from_native() got an unexpected keyword argument {next(iter(kwds))!r}"
+ raise TypeError(msg)
+
+ return _from_native_impl( # type: ignore[no-any-return]
+ native_object,
+ pass_through=pass_through,
+ eager_only=eager_only,
+ eager_or_interchange_only=eager_or_interchange_only,
+ series_only=series_only,
+ allow_series=allow_series,
+ version=Version.V1,
+ )
+
+
+@overload
+def to_native(
+ narwhals_object: DataFrame[IntoDataFrameT], *, strict: Literal[True] = ...
+) -> IntoDataFrameT: ...
+@overload
+def to_native(
+ narwhals_object: LazyFrame[IntoFrameT], *, strict: Literal[True] = ...
+) -> IntoFrameT: ...
+@overload
+def to_native(
+ narwhals_object: Series[IntoSeriesT], *, strict: Literal[True] = ...
+) -> IntoSeriesT: ...
+@overload
+def to_native(narwhals_object: Any, *, strict: bool) -> Any: ...
+@overload
+def to_native(
+ narwhals_object: DataFrame[IntoDataFrameT], *, pass_through: Literal[False] = ...
+) -> IntoDataFrameT: ...
+@overload
+def to_native(
+ narwhals_object: LazyFrame[IntoFrameT], *, pass_through: Literal[False] = ...
+) -> IntoFrameT: ...
+@overload
+def to_native(
+ narwhals_object: Series[IntoSeriesT], *, pass_through: Literal[False] = ...
+) -> IntoSeriesT: ...
+@overload
+def to_native(narwhals_object: Any, *, pass_through: bool) -> Any: ...
+
+
+def to_native(
+ narwhals_object: DataFrame[IntoDataFrameT]
+ | LazyFrame[IntoFrameT]
+ | Series[IntoSeriesT],
+ *,
+ strict: bool | None = None,
+ pass_through: bool | None = None,
+) -> IntoFrameT | IntoSeriesT | Any:
+ """Convert Narwhals object to native one.
+
+ See `narwhals.to_native` for full docstring. Note that `native_namespace` is
+ an is the same as `backend` but only accepts module types - for new code, we
+ recommend using `backend`, as that's available beyond just `narwhals.stable.v1`.
+ """
+ from narwhals._utils import validate_strict_and_pass_though
+
+ pass_through = validate_strict_and_pass_though(
+ strict, pass_through, pass_through_default=False
+ )
+ return nw.to_native(narwhals_object, pass_through=pass_through)
+
+
+def narwhalify(
+ func: Callable[..., Any] | None = None,
+ *,
+ strict: bool | None = None,
+ pass_through: bool | None = None,
+ eager_only: bool = False,
+ eager_or_interchange_only: bool = False,
+ series_only: bool = False,
+ allow_series: bool | None = True,
+) -> Callable[..., Any]:
+ """Decorate function so it becomes dataframe-agnostic.
+
+ See `narwhals.narwhalify` for full docstring. Note that `native_namespace` is
+ an is the same as `backend` but only accepts module types - for new code, we
+ recommend using `backend`, as that's available beyond just `narwhals.stable.v1`.
+ """
+ pass_through = validate_strict_and_pass_though(
+ strict, pass_through, pass_through_default=True
+ )
+
+ def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
+ @wraps(func)
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
+ args = [
+ from_native(
+ arg,
+ pass_through=pass_through,
+ eager_only=eager_only,
+ eager_or_interchange_only=eager_or_interchange_only,
+ series_only=series_only,
+ allow_series=allow_series,
+ )
+ for arg in args
+ ] # type: ignore[assignment]
+
+ kwargs = {
+ name: from_native(
+ value,
+ pass_through=pass_through,
+ eager_only=eager_only,
+ eager_or_interchange_only=eager_or_interchange_only,
+ series_only=series_only,
+ allow_series=allow_series,
+ )
+ for name, value in kwargs.items()
+ }
+
+ backends = {
+ b()
+ for v in (*args, *kwargs.values())
+ if (b := getattr(v, "__native_namespace__", None))
+ }
+
+ if backends.__len__() > 1:
+ msg = "Found multiple backends. Make sure that all dataframe/series inputs come from the same backend."
+ raise ValueError(msg)
+
+ result = func(*args, **kwargs)
+
+ return to_native(result, pass_through=pass_through)
+
+ return wrapper
+
+ if func is None:
+ return decorator
+ else:
+ # If func is not None, it means the decorator is used without arguments
+ return decorator(func)
+
+
+def all() -> Expr:
+ return _stableify(nw.all())
+
+
+def col(*names: str | Iterable[str]) -> Expr:
+ return _stableify(nw.col(*names))
+
+
+def exclude(*names: str | Iterable[str]) -> Expr:
+ return _stableify(nw.exclude(*names))
+
+
+def nth(*indices: int | Sequence[int]) -> Expr:
+ return _stableify(nw.nth(*indices))
+
+
+def len() -> Expr:
+ return _stableify(nw.len())
+
+
+def lit(value: NonNestedLiteral, dtype: IntoDType | None = None) -> Expr:
+ return _stableify(nw.lit(value, dtype))
+
+
+def min(*columns: str) -> Expr:
+ return _stableify(nw.min(*columns))
+
+
+def max(*columns: str) -> Expr:
+ return _stableify(nw.max(*columns))
+
+
+def mean(*columns: str) -> Expr:
+ return _stableify(nw.mean(*columns))
+
+
+def median(*columns: str) -> Expr:
+ return _stableify(nw.median(*columns))
+
+
+def sum(*columns: str) -> Expr:
+ return _stableify(nw.sum(*columns))
+
+
+def sum_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
+ return _stableify(nw.sum_horizontal(*exprs))
+
+
+def all_horizontal(
+ *exprs: IntoExpr | Iterable[IntoExpr], ignore_nulls: bool = False
+) -> Expr:
+ return _stableify(nw.all_horizontal(*exprs, ignore_nulls=ignore_nulls))
+
+
+def any_horizontal(
+ *exprs: IntoExpr | Iterable[IntoExpr], ignore_nulls: bool = False
+) -> Expr:
+ return _stableify(nw.any_horizontal(*exprs, ignore_nulls=ignore_nulls))
+
+
+def mean_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
+ return _stableify(nw.mean_horizontal(*exprs))
+
+
+def min_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
+ return _stableify(nw.min_horizontal(*exprs))
+
+
+def max_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
+ return _stableify(nw.max_horizontal(*exprs))
+
+
+def concat_str(
+ exprs: IntoExpr | Iterable[IntoExpr],
+ *more_exprs: IntoExpr,
+ separator: str = "",
+ ignore_nulls: bool = False,
+) -> Expr:
+ return _stableify(
+ nw.concat_str(exprs, *more_exprs, separator=separator, ignore_nulls=ignore_nulls)
+ )
+
+
+def coalesce(exprs: IntoExpr | Iterable[IntoExpr], *more_exprs: IntoExpr) -> Expr:
+ return _stableify(nw.coalesce(exprs, *more_exprs))
+
+
+def get_level(
+ obj: DataFrame[Any] | LazyFrame[Any] | Series[IntoSeriesT],
+) -> Literal["full", "lazy", "interchange"]:
+ """Level of support Narwhals has for current object.
+
+ Arguments:
+ obj: Dataframe or Series.
+
+ Returns:
+ This can be one of
+
+ - 'full': full Narwhals API support
+ - 'lazy': only lazy operations are supported. This excludes anything
+ which involves iterating over rows in Python.
+ - 'interchange': only metadata operations are supported (`df.schema`)
+ """
+ return obj._level
+
+
+class When(nw_f.When):
+ @classmethod
+ def from_when(cls, when: nw_f.When) -> When:
+ return cls(when._predicate)
+
+ def then(self, value: IntoExpr | NonNestedLiteral | _1DArray) -> Then:
+ return Then.from_then(super().then(value))
+
+
+class Then(nw_f.Then, Expr):
+ @classmethod
+ def from_then(cls, then: nw_f.Then) -> Then:
+ return cls(then._to_compliant_expr, then._metadata)
+
+ def otherwise(self, value: IntoExpr | NonNestedLiteral | _1DArray) -> Expr:
+ return _stableify(super().otherwise(value))
+
+
+def when(*predicates: IntoExpr | Iterable[IntoExpr]) -> When:
+ return When.from_when(nw_f.when(*predicates))
+
+
+@deprecate_native_namespace(required=True)
+def new_series(
+ name: str,
+ values: Any,
+ dtype: IntoDType | None = None,
+ *,
+ backend: ModuleType | Implementation | str | None = None,
+ native_namespace: ModuleType | None = None, # noqa: ARG001
+) -> Series[Any]:
+ """Instantiate Narwhals Series from iterable (e.g. list or array).
+
+ See `narwhals.new_series` for full docstring. Note that `native_namespace` is
+ an is the same as `backend` but only accepts module types - for new code, we
+ recommend using `backend`, as that's available beyond just `narwhals.stable.v1`.
+ """
+ backend = cast("ModuleType | Implementation | str", backend)
+ return _stableify(_new_series_impl(name, values, dtype, backend=backend))
+
+
+@deprecate_native_namespace(required=True)
+def from_arrow(
+ native_frame: IntoArrowTable,
+ *,
+ backend: ModuleType | Implementation | str | None = None,
+ native_namespace: ModuleType | None = None, # noqa: ARG001
+) -> DataFrame[Any]:
+ """Construct a DataFrame from an object which supports the PyCapsule Interface.
+
+ See `narwhals.from_arrow` for full docstring. Note that `native_namespace` is
+ an is the same as `backend` but only accepts module types - for new code, we
+ recommend using `backend`, as that's available beyond just `narwhals.stable.v1`.
+ """
+ backend = cast("ModuleType | Implementation | str", backend)
+ return _stableify(nw_f.from_arrow(native_frame, backend=backend))
+
+
+@deprecate_native_namespace()
+def from_dict(
+ data: Mapping[str, Any],
+ schema: Mapping[str, DType] | Schema | None = None,
+ *,
+ backend: ModuleType | Implementation | str | None = None,
+ native_namespace: ModuleType | None = None, # noqa: ARG001
+) -> DataFrame[Any]:
+ """Instantiate DataFrame from dictionary.
+
+ See `narwhals.from_dict` for full docstring. Note that `native_namespace` is
+ an is the same as `backend` but only accepts module types - for new code, we
+ recommend using `backend`, as that's available beyond just `narwhals.stable.v1`.
+ """
+ return _stableify(nw_f.from_dict(data, schema, backend=backend))
+
+
+@deprecate_native_namespace(required=True)
+def from_numpy(
+ data: _2DArray,
+ schema: Mapping[str, DType] | Schema | Sequence[str] | None = None,
+ *,
+ backend: ModuleType | Implementation | str | None = None,
+ native_namespace: ModuleType | None = None, # noqa: ARG001
+) -> DataFrame[Any]:
+ """Construct a DataFrame from a NumPy ndarray.
+
+ See `narwhals.from_numpy` for full docstring. Note that `native_namespace` is
+ an is the same as `backend` but only accepts module types - for new code, we
+ recommend using `backend`, as that's available beyond just `narwhals.stable.v1`.
+ """
+ backend = cast("ModuleType | Implementation | str", backend)
+ return _stableify(nw_f.from_numpy(data, schema, backend=backend))
+
+
+@deprecate_native_namespace(required=True)
+def read_csv(
+ source: str,
+ *,
+ backend: ModuleType | Implementation | str | None = None,
+ native_namespace: ModuleType | None = None, # noqa: ARG001
+ **kwargs: Any,
+) -> DataFrame[Any]:
+ """Read a CSV file into a DataFrame.
+
+ See `narwhals.read_csv` for full docstring. Note that `native_namespace` is
+ an is the same as `backend` but only accepts module types - for new code, we
+ recommend using `backend`, as that's available beyond just `narwhals.stable.v1`.
+ """
+ backend = cast("ModuleType | Implementation | str", backend)
+ return _stableify(nw_f.read_csv(source, backend=backend, **kwargs))
+
+
+@deprecate_native_namespace(required=True)
+def scan_csv(
+ source: str,
+ *,
+ backend: ModuleType | Implementation | str | None = None,
+ native_namespace: ModuleType | None = None, # noqa: ARG001
+ **kwargs: Any,
+) -> LazyFrame[Any]:
+ """Lazily read from a CSV file.
+
+ See `narwhals.scan_csv` for full docstring. Note that `native_namespace` is
+ an is the same as `backend` but only accepts module types - for new code, we
+ recommend using `backend`, as that's available beyond just `narwhals.stable.v1`.
+ """
+ backend = cast("ModuleType | Implementation | str", backend)
+ return _stableify(nw_f.scan_csv(source, backend=backend, **kwargs))
+
+
+@deprecate_native_namespace(required=True)
+def read_parquet(
+ source: str,
+ *,
+ backend: ModuleType | Implementation | str | None = None,
+ native_namespace: ModuleType | None = None, # noqa: ARG001
+ **kwargs: Any,
+) -> DataFrame[Any]:
+ """Read into a DataFrame from a parquet file.
+
+ See `narwhals.read_parquet` for full docstring. Note that `native_namespace` is
+ an is the same as `backend` but only accepts module types - for new code, we
+ recommend using `backend`, as that's available beyond just `narwhals.stable.v1`.
+ """
+ backend = cast("ModuleType | Implementation | str", backend)
+ return _stableify(nw_f.read_parquet(source, backend=backend, **kwargs))
+
+
+@deprecate_native_namespace(required=True)
+def scan_parquet(
+ source: str,
+ *,
+ backend: ModuleType | Implementation | str | None = None,
+ native_namespace: ModuleType | None = None, # noqa: ARG001
+ **kwargs: Any,
+) -> LazyFrame[Any]:
+ """Lazily read from a parquet file.
+
+ See `narwhals.scan_parquet` for full docstring. Note that `native_namespace` is
+ an is the same as `backend` but only accepts module types - for new code, we
+ recommend using `backend`, as that's available beyond just `narwhals.stable.v1`.
+ """
+ backend = cast("ModuleType | Implementation | str", backend)
+ return _stableify(nw_f.scan_parquet(source, backend=backend, **kwargs))
+
+
+__all__ = [
+ "Array",
+ "Binary",
+ "Boolean",
+ "Categorical",
+ "DataFrame",
+ "Date",
+ "Datetime",
+ "Decimal",
+ "Duration",
+ "Enum",
+ "Expr",
+ "Field",
+ "Float32",
+ "Float64",
+ "Implementation",
+ "Int8",
+ "Int16",
+ "Int32",
+ "Int64",
+ "Int128",
+ "LazyFrame",
+ "List",
+ "Object",
+ "Schema",
+ "Series",
+ "String",
+ "Struct",
+ "Time",
+ "UInt8",
+ "UInt16",
+ "UInt32",
+ "UInt64",
+ "UInt128",
+ "Unknown",
+ "all",
+ "all_horizontal",
+ "any_horizontal",
+ "coalesce",
+ "col",
+ "concat",
+ "concat_str",
+ "dependencies",
+ "dtypes",
+ "exceptions",
+ "exclude",
+ "from_arrow",
+ "from_dict",
+ "from_native",
+ "from_numpy",
+ "generate_temporary_column_name",
+ "get_level",
+ "get_native_namespace",
+ "is_ordered_categorical",
+ "len",
+ "lit",
+ "max",
+ "max_horizontal",
+ "maybe_align_index",
+ "maybe_convert_dtypes",
+ "maybe_get_index",
+ "maybe_reset_index",
+ "maybe_set_index",
+ "mean",
+ "mean_horizontal",
+ "median",
+ "min",
+ "min_horizontal",
+ "narwhalify",
+ "new_series",
+ "nth",
+ "read_csv",
+ "read_parquet",
+ "scan_csv",
+ "scan_parquet",
+ "selectors",
+ "show_versions",
+ "sum",
+ "sum_horizontal",
+ "to_native",
+ "to_py_scalar",
+ "when",
+]
diff --git a/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/__init__.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9f354e02c8a7c39acaaa482e0da9c08970935dad
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/__init__.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/_dtypes.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/_dtypes.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d90e1de3c7c7ec2060b52ce7b8cca4b7eb7fb71d
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/_dtypes.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/_namespace.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/_namespace.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e7a224d9979ba8f2670a99092cf68cec493b07d7
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/_namespace.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/dependencies.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/dependencies.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d3f26e5265d180c3eb55c7d54ae79f135bdc2fff
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/dependencies.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/dtypes.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/dtypes.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ec49e1ce10ecf027bf55a21761274eac9bd28fc1
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/dtypes.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/selectors.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/selectors.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fb62bc814bd44764220a94850a1a886753b4219b
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/selectors.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/typing.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/typing.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e0685080ab394d380ce57767e2df0309fd35bbde
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/stable/v1/__pycache__/typing.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/stable/v1/_dtypes.py b/lib/python3.10/site-packages/narwhals/stable/v1/_dtypes.py
new file mode 100644
index 0000000000000000000000000000000000000000..060980c562dbfae73586c70150b4a5709dc6a2aa
--- /dev/null
+++ b/lib/python3.10/site-packages/narwhals/stable/v1/_dtypes.py
@@ -0,0 +1,135 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+
+from narwhals._utils import inherit_doc
+from narwhals.dtypes import (
+ Array,
+ Binary,
+ Boolean,
+ Categorical,
+ Date,
+ Datetime as NwDatetime,
+ Decimal,
+ DType,
+ Duration as NwDuration,
+ Enum as NwEnum,
+ Field,
+ Float32,
+ Float64,
+ FloatType,
+ Int8,
+ Int16,
+ Int32,
+ Int64,
+ Int128,
+ IntegerType,
+ List,
+ NestedType,
+ NumericType,
+ Object,
+ SignedIntegerType,
+ String,
+ Struct,
+ Time,
+ UInt8,
+ UInt16,
+ UInt32,
+ UInt64,
+ UInt128,
+ Unknown,
+ UnsignedIntegerType,
+)
+
+if TYPE_CHECKING:
+ from datetime import timezone
+
+ from narwhals.typing import TimeUnit
+
+
+class Datetime(NwDatetime):
+ @inherit_doc(NwDatetime)
+ def __init__(
+ self, time_unit: TimeUnit = "us", time_zone: str | timezone | None = None
+ ) -> None:
+ super().__init__(time_unit, time_zone)
+
+ def __hash__(self) -> int:
+ return hash(self.__class__)
+
+
+class Duration(NwDuration):
+ @inherit_doc(NwDuration)
+ def __init__(self, time_unit: TimeUnit = "us") -> None:
+ super().__init__(time_unit)
+
+ def __hash__(self) -> int:
+ return hash(self.__class__)
+
+
+class Enum(NwEnum):
+ """A fixed categorical encoding of a unique set of strings.
+
+ Polars has an Enum data type, while pandas and PyArrow do not.
+
+ Examples:
+ >>> import polars as pl
+ >>> import narwhals.stable.v1 as nw
+ >>> data = ["beluga", "narwhal", "orca"]
+ >>> s_native = pl.Series(data, dtype=pl.Enum(data))
+ >>> nw.from_native(s_native, series_only=True).dtype
+ Enum
+ """
+
+ def __init__(self) -> None:
+ super(NwEnum, self).__init__()
+
+ def __eq__(self, other: DType | type[DType]) -> bool: # type: ignore[override]
+ if type(other) is type:
+ return other in {type(self), NwEnum}
+ return isinstance(other, type(self))
+
+ def __hash__(self) -> int: # pragma: no cover
+ return super(NwEnum, self).__hash__()
+
+ def __repr__(self) -> str: # pragma: no cover
+ return super(NwEnum, self).__repr__()
+
+
+__all__ = [
+ "Array",
+ "Binary",
+ "Boolean",
+ "Categorical",
+ "DType",
+ "Date",
+ "Datetime",
+ "Decimal",
+ "Duration",
+ "Enum",
+ "Field",
+ "Float32",
+ "Float64",
+ "FloatType",
+ "Int8",
+ "Int16",
+ "Int32",
+ "Int64",
+ "Int128",
+ "IntegerType",
+ "List",
+ "NestedType",
+ "NumericType",
+ "Object",
+ "SignedIntegerType",
+ "String",
+ "Struct",
+ "Time",
+ "UInt8",
+ "UInt16",
+ "UInt32",
+ "UInt64",
+ "UInt128",
+ "Unknown",
+ "UnsignedIntegerType",
+]
diff --git a/lib/python3.10/site-packages/narwhals/stable/v1/_namespace.py b/lib/python3.10/site-packages/narwhals/stable/v1/_namespace.py
new file mode 100644
index 0000000000000000000000000000000000000000..8f11f0110216efc73bbc579e6a0656d86e21115e
--- /dev/null
+++ b/lib/python3.10/site-packages/narwhals/stable/v1/_namespace.py
@@ -0,0 +1,10 @@
+from __future__ import annotations
+
+from narwhals._compliant.typing import CompliantNamespaceT_co
+from narwhals._namespace import Namespace as NwNamespace
+from narwhals._utils import Version
+
+__all__ = ["Namespace"]
+
+
+class Namespace(NwNamespace[CompliantNamespaceT_co], version=Version.V1): ...
diff --git a/lib/python3.10/site-packages/narwhals/stable/v1/dependencies.py b/lib/python3.10/site-packages/narwhals/stable/v1/dependencies.py
new file mode 100644
index 0000000000000000000000000000000000000000..2674f2890f057bd657f178e0b70f09596410d376
--- /dev/null
+++ b/lib/python3.10/site-packages/narwhals/stable/v1/dependencies.py
@@ -0,0 +1,156 @@
+from __future__ import annotations
+
+import sys
+from typing import TYPE_CHECKING, Any
+
+if TYPE_CHECKING:
+ import cudf
+ import dask.dataframe as dd
+ import ibis
+ import modin.pandas as mpd
+ import pandas as pd
+ import polars as pl
+ import pyarrow as pa
+ from typing_extensions import TypeIs
+
+
+from narwhals.dependencies import (
+ IMPORT_HOOKS,
+ get_cudf,
+ get_dask_dataframe,
+ get_ibis,
+ get_modin,
+ get_numpy,
+ get_pandas,
+ get_polars,
+ get_pyarrow,
+ is_into_dataframe,
+ is_into_series,
+ is_narwhals_dataframe,
+ is_narwhals_lazyframe,
+ is_narwhals_series,
+ is_numpy_array,
+ is_pandas_index,
+)
+
+
+def is_pandas_dataframe(df: Any) -> TypeIs[pd.DataFrame]:
+ """Check whether `df` is a pandas DataFrame without importing pandas."""
+ return ((pd := get_pandas()) is not None and isinstance(df, pd.DataFrame)) or any(
+ (mod := sys.modules.get(module_name, None)) is not None
+ and isinstance(df, mod.pandas.DataFrame)
+ for module_name in IMPORT_HOOKS
+ )
+
+
+def is_pandas_series(ser: Any) -> TypeIs[pd.Series[Any]]:
+ """Check whether `ser` is a pandas Series without importing pandas."""
+ return ((pd := get_pandas()) is not None and isinstance(ser, pd.Series)) or any(
+ (mod := sys.modules.get(module_name, None)) is not None
+ and isinstance(ser, mod.pandas.Series)
+ for module_name in IMPORT_HOOKS
+ )
+
+
+def is_modin_dataframe(df: Any) -> TypeIs[mpd.DataFrame]:
+ """Check whether `df` is a modin DataFrame without importing modin."""
+ return (mpd := get_modin()) is not None and isinstance(df, mpd.DataFrame)
+
+
+def is_modin_series(ser: Any) -> TypeIs[mpd.Series]:
+ """Check whether `ser` is a modin Series without importing modin."""
+ return (mpd := get_modin()) is not None and isinstance(ser, mpd.Series)
+
+
+def is_cudf_dataframe(df: Any) -> TypeIs[cudf.DataFrame]:
+ """Check whether `df` is a cudf DataFrame without importing cudf."""
+ return (cudf := get_cudf()) is not None and isinstance(df, cudf.DataFrame)
+
+
+def is_cudf_series(ser: Any) -> TypeIs[cudf.Series[Any]]:
+ """Check whether `ser` is a cudf Series without importing cudf."""
+ return (cudf := get_cudf()) is not None and isinstance(ser, cudf.Series)
+
+
+def is_dask_dataframe(df: Any) -> TypeIs[dd.DataFrame]:
+ """Check whether `df` is a Dask DataFrame without importing Dask."""
+ return (dd := get_dask_dataframe()) is not None and isinstance(df, dd.DataFrame)
+
+
+def is_ibis_table(df: Any) -> TypeIs[ibis.Table]:
+ """Check whether `df` is a Ibis Table without importing Ibis."""
+ return (ibis := get_ibis()) is not None and isinstance(df, ibis.expr.types.Table)
+
+
+def is_polars_dataframe(df: Any) -> TypeIs[pl.DataFrame]:
+ """Check whether `df` is a Polars DataFrame without importing Polars."""
+ return (pl := get_polars()) is not None and isinstance(df, pl.DataFrame)
+
+
+def is_polars_lazyframe(df: Any) -> TypeIs[pl.LazyFrame]:
+ """Check whether `df` is a Polars LazyFrame without importing Polars."""
+ return (pl := get_polars()) is not None and isinstance(df, pl.LazyFrame)
+
+
+def is_polars_series(ser: Any) -> TypeIs[pl.Series]:
+ """Check whether `ser` is a Polars Series without importing Polars."""
+ return (pl := get_polars()) is not None and isinstance(ser, pl.Series)
+
+
+def is_pyarrow_chunked_array(ser: Any) -> TypeIs[pa.ChunkedArray[Any]]:
+ """Check whether `ser` is a PyArrow ChunkedArray without importing PyArrow."""
+ return (pa := get_pyarrow()) is not None and isinstance(ser, pa.ChunkedArray)
+
+
+def is_pyarrow_table(df: Any) -> TypeIs[pa.Table]:
+ """Check whether `df` is a PyArrow Table without importing PyArrow."""
+ return (pa := get_pyarrow()) is not None and isinstance(df, pa.Table)
+
+
+def is_pandas_like_dataframe(df: Any) -> bool:
+ """Check whether `df` is a pandas-like DataFrame without doing any imports.
+
+ By "pandas-like", we mean: pandas, Modin, cuDF.
+ """
+ return is_pandas_dataframe(df) or is_modin_dataframe(df) or is_cudf_dataframe(df)
+
+
+def is_pandas_like_series(ser: Any) -> bool:
+ """Check whether `ser` is a pandas-like Series without doing any imports.
+
+ By "pandas-like", we mean: pandas, Modin, cuDF.
+ """
+ return is_pandas_series(ser) or is_modin_series(ser) or is_cudf_series(ser)
+
+
+__all__ = [
+ "get_cudf",
+ "get_ibis",
+ "get_modin",
+ "get_numpy",
+ "get_pandas",
+ "get_polars",
+ "get_pyarrow",
+ "is_cudf_dataframe",
+ "is_cudf_series",
+ "is_dask_dataframe",
+ "is_ibis_table",
+ "is_into_dataframe",
+ "is_into_series",
+ "is_modin_dataframe",
+ "is_modin_series",
+ "is_narwhals_dataframe",
+ "is_narwhals_lazyframe",
+ "is_narwhals_series",
+ "is_numpy_array",
+ "is_pandas_dataframe",
+ "is_pandas_index",
+ "is_pandas_like_dataframe",
+ "is_pandas_like_series",
+ "is_pandas_series",
+ "is_polars_dataframe",
+ "is_polars_lazyframe",
+ "is_polars_series",
+ "is_pyarrow_chunked_array",
+ "is_pyarrow_table",
+]
diff --git a/lib/python3.10/site-packages/narwhals/stable/v1/dtypes.py b/lib/python3.10/site-packages/narwhals/stable/v1/dtypes.py
new file mode 100644
index 0000000000000000000000000000000000000000..a292be8a6010cd39b3c230132dad72e98d5346ab
--- /dev/null
+++ b/lib/python3.10/site-packages/narwhals/stable/v1/dtypes.py
@@ -0,0 +1,77 @@
+from __future__ import annotations
+
+from narwhals.stable.v1._dtypes import (
+ Array,
+ Binary,
+ Boolean,
+ Categorical,
+ Date,
+ Datetime,
+ Decimal,
+ DType,
+ Duration,
+ Enum,
+ Field,
+ Float32,
+ Float64,
+ FloatType,
+ Int8,
+ Int16,
+ Int32,
+ Int64,
+ Int128,
+ IntegerType,
+ List,
+ NestedType,
+ NumericType,
+ Object,
+ SignedIntegerType,
+ String,
+ Struct,
+ Time,
+ UInt8,
+ UInt16,
+ UInt32,
+ UInt64,
+ UInt128,
+ Unknown,
+ UnsignedIntegerType,
+)
+
+__all__ = [
+ "Array",
+ "Binary",
+ "Boolean",
+ "Categorical",
+ "DType",
+ "Date",
+ "Datetime",
+ "Decimal",
+ "Duration",
+ "Enum",
+ "Field",
+ "Float32",
+ "Float64",
+ "FloatType",
+ "Int8",
+ "Int16",
+ "Int32",
+ "Int64",
+ "Int128",
+ "IntegerType",
+ "List",
+ "NestedType",
+ "NumericType",
+ "Object",
+ "SignedIntegerType",
+ "String",
+ "Struct",
+ "Time",
+ "UInt8",
+ "UInt16",
+ "UInt32",
+ "UInt64",
+ "UInt128",
+ "Unknown",
+ "UnsignedIntegerType",
+]
diff --git a/lib/python3.10/site-packages/narwhals/stable/v1/selectors.py b/lib/python3.10/site-packages/narwhals/stable/v1/selectors.py
new file mode 100644
index 0000000000000000000000000000000000000000..ede128eb3cff3f36781c20e64cb0e25c0dbfce55
--- /dev/null
+++ b/lib/python3.10/site-packages/narwhals/stable/v1/selectors.py
@@ -0,0 +1,23 @@
+from __future__ import annotations
+
+from narwhals.selectors import (
+ all,
+ boolean,
+ by_dtype,
+ categorical,
+ datetime,
+ matches,
+ numeric,
+ string,
+)
+
+__all__ = [
+ "all",
+ "boolean",
+ "by_dtype",
+ "categorical",
+ "datetime",
+ "matches",
+ "numeric",
+ "string",
+]
diff --git a/lib/python3.10/site-packages/narwhals/stable/v1/typing.py b/lib/python3.10/site-packages/narwhals/stable/v1/typing.py
new file mode 100644
index 0000000000000000000000000000000000000000..c3a0b421bc2103ef6f787f904245b6a553f29055
--- /dev/null
+++ b/lib/python3.10/site-packages/narwhals/stable/v1/typing.py
@@ -0,0 +1,183 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any, Protocol, TypeVar, Union
+
+if TYPE_CHECKING:
+ import sys
+
+ from narwhals.stable.v1 import DataFrame, LazyFrame
+
+ if sys.version_info >= (3, 10):
+ from typing import TypeAlias
+ else:
+ from typing_extensions import TypeAlias
+
+ from narwhals.stable.v1 import Expr, Series
+
+ # All dataframes supported by Narwhals have a
+ # `columns` property. Their similarities don't extend
+ # _that_ much further unfortunately...
+ class NativeFrame(Protocol):
+ @property
+ def columns(self) -> Any: ...
+
+ def join(self, *args: Any, **kwargs: Any) -> Any: ...
+
+ class NativeSeries(Protocol):
+ def __len__(self) -> int: ...
+
+ class DataFrameLike(Protocol):
+ def __dataframe__(self, *args: Any, **kwargs: Any) -> Any: ...
+
+
+IntoExpr: TypeAlias = Union["Expr", str, "Series[Any]"]
+"""Anything which can be converted to an expression.
+
+Use this to mean "either a Narwhals expression, or something
+which can be converted into one". For example, `exprs` in `DataFrame.select` is
+typed to accept `IntoExpr`, as it can either accept a `nw.Expr`
+(e.g. `df.select(nw.col('a'))`) or a string which will be interpreted as a
+`nw.Expr`, e.g. `df.select('a')`.
+"""
+
+IntoDataFrame: TypeAlias = Union["NativeFrame", "DataFrame[Any]", "DataFrameLike"]
+"""Anything which can be converted to a Narwhals DataFrame.
+
+Use this if your function accepts a narwhalifiable object but doesn't care about its backend.
+
+Examples:
+ >>> import narwhals as nw
+ >>> from narwhals.typing import IntoDataFrame
+ >>> def agnostic_shape(df_native: IntoDataFrame) -> tuple[int, int]:
+ ... df = nw.from_native(df_native, eager_only=True)
+ ... return df.shape
+"""
+
+IntoFrame: TypeAlias = Union[
+ "NativeFrame", "DataFrame[Any]", "LazyFrame[Any]", "DataFrameLike"
+]
+"""Anything which can be converted to a Narwhals DataFrame or LazyFrame.
+
+Use this if your function can accept an object which can be converted to either
+`nw.DataFrame` or `nw.LazyFrame` and it doesn't care about its backend.
+
+Examples:
+ >>> import narwhals as nw
+ >>> from narwhals.typing import IntoFrame
+ >>> def agnostic_columns(df_native: IntoFrame) -> list[str]:
+ ... df = nw.from_native(df_native)
+ ... return df.collect_schema().names()
+"""
+
+Frame: TypeAlias = Union["DataFrame[Any]", "LazyFrame[Any]"]
+"""Narwhals DataFrame or Narwhals LazyFrame.
+
+Use this if your function can work with either and your function doesn't care
+about its backend.
+
+Examples:
+ >>> import narwhals as nw
+ >>> from narwhals.typing import Frame
+ >>> @nw.narwhalify
+ ... def agnostic_columns(df: Frame) -> list[str]:
+ ... return df.columns
+"""
+
+IntoSeries: TypeAlias = Union["Series[Any]", "NativeSeries"]
+"""Anything which can be converted to a Narwhals Series.
+
+Use this if your function can accept an object which can be converted to `nw.Series`
+and it doesn't care about its backend.
+
+Examples:
+ >>> from typing import Any
+ >>> import narwhals as nw
+ >>> from narwhals.typing import IntoSeries
+ >>> def agnostic_to_list(s_native: IntoSeries) -> list[Any]:
+ ... s = nw.from_native(s_native)
+ ... return s.to_list()
+"""
+
+IntoFrameT = TypeVar("IntoFrameT", bound="IntoFrame")
+"""TypeVar bound to object convertible to Narwhals DataFrame or Narwhals LazyFrame.
+
+Use this if your function accepts an object which is convertible to `nw.DataFrame`
+or `nw.LazyFrame` and returns an object of the same type.
+
+Examples:
+ >>> import narwhals as nw
+ >>> from narwhals.typing import IntoFrameT
+ >>> def agnostic_func(df_native: IntoFrameT) -> IntoFrameT:
+ ... df = nw.from_native(df_native)
+ ... return df.with_columns(c=nw.col("a") + 1).to_native()
+"""
+
+IntoDataFrameT = TypeVar("IntoDataFrameT", bound="IntoDataFrame")
+"""TypeVar bound to object convertible to Narwhals DataFrame.
+
+Use this if your function accepts an object which can be converted to `nw.DataFrame`
+and returns an object of the same class.
+
+Examples:
+ >>> import narwhals as nw
+ >>> from narwhals.typing import IntoDataFrameT
+ >>> def agnostic_func(df_native: IntoDataFrameT) -> IntoDataFrameT:
+ ... df = nw.from_native(df_native, eager_only=True)
+ ... return df.with_columns(c=df["a"] + 1).to_native()
+"""
+
+FrameT = TypeVar("FrameT", "DataFrame[Any]", "LazyFrame[Any]")
+"""TypeVar bound to Narwhals DataFrame or Narwhals LazyFrame.
+
+Use this if your function accepts either `nw.DataFrame` or `nw.LazyFrame` and returns
+an object of the same kind.
+
+Examples:
+ >>> import narwhals as nw
+ >>> from narwhals.typing import FrameT
+ >>> @nw.narwhalify
+ ... def agnostic_func(df: FrameT) -> FrameT:
+ ... return df.with_columns(c=nw.col("a") + 1)
+"""
+
+DataFrameT = TypeVar("DataFrameT", bound="DataFrame[Any]")
+"""TypeVar bound to Narwhals DataFrame.
+
+Use this if your function can accept a Narwhals DataFrame and returns a Narwhals
+DataFrame backed by the same backend.
+
+Examples:
+ >>> import narwhals as nw
+ >>> from narwhals.typing import DataFrameT
+ >>> @nw.narwhalify
+ >>> def func(df: DataFrameT) -> DataFrameT:
+ ... return df.with_columns(c=df["a"] + 1)
+"""
+
+IntoSeriesT = TypeVar("IntoSeriesT", bound="IntoSeries")
+"""TypeVar bound to object convertible to Narwhals Series.
+
+Use this if your function accepts an object which can be converted to `nw.Series`
+and returns an object of the same class.
+
+Examples:
+ >>> import narwhals as nw
+ >>> from narwhals.typing import IntoSeriesT
+ >>> def agnostic_abs(s_native: IntoSeriesT) -> IntoSeriesT:
+ ... s = nw.from_native(s_native, series_only=True)
+ ... return s.abs().to_native()
+"""
+
+
+__all__ = [
+ "DataFrameT",
+ "Frame",
+ "FrameT",
+ "IntoDataFrame",
+ "IntoDataFrameT",
+ "IntoExpr",
+ "IntoFrame",
+ "IntoFrameT",
+ "IntoSeries",
+ "IntoSeriesT",
+]
diff --git a/lib/python3.10/site-packages/narwhals/stable/v2/__init__.py b/lib/python3.10/site-packages/narwhals/stable/v2/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..93cd912b8a893834c070583ae4fafbe6668e2d7d
--- /dev/null
+++ b/lib/python3.10/site-packages/narwhals/stable/v2/__init__.py
@@ -0,0 +1,1257 @@
+from __future__ import annotations
+
+from functools import wraps
+from typing import TYPE_CHECKING, Any, Callable, Literal, cast, overload
+
+import narwhals as nw
+from narwhals import exceptions, functions as nw_f
+from narwhals._typing_compat import TypeVar, assert_never
+from narwhals._utils import (
+ Implementation,
+ Version,
+ generate_temporary_column_name,
+ inherit_doc,
+ is_ordered_categorical,
+ maybe_align_index,
+ maybe_convert_dtypes,
+ maybe_get_index,
+ maybe_reset_index,
+ maybe_set_index,
+ not_implemented,
+)
+from narwhals.dataframe import DataFrame as NwDataFrame, LazyFrame as NwLazyFrame
+from narwhals.dtypes import (
+ Array,
+ Binary,
+ Boolean,
+ Categorical,
+ Date,
+ Datetime,
+ Decimal,
+ Duration,
+ Enum,
+ Field,
+ Float32,
+ Float64,
+ Int8,
+ Int16,
+ Int32,
+ Int64,
+ Int128,
+ List,
+ Object,
+ String,
+ Struct,
+ Time,
+ UInt8,
+ UInt16,
+ UInt32,
+ UInt64,
+ UInt128,
+ Unknown,
+)
+from narwhals.expr import Expr as NwExpr
+from narwhals.functions import _new_series_impl, concat, show_versions
+from narwhals.schema import Schema as NwSchema
+from narwhals.series import Series as NwSeries
+from narwhals.stable.v2 import dependencies, dtypes, selectors
+from narwhals.translate import _from_native_impl, get_native_namespace, to_py_scalar
+from narwhals.typing import IntoDataFrameT, IntoFrameT
+
+if TYPE_CHECKING:
+ from collections.abc import Iterable, Mapping, Sequence
+ from types import ModuleType
+
+ from typing_extensions import ParamSpec, Self
+
+ from narwhals._translate import IntoArrowTable
+ from narwhals.dataframe import MultiColSelector, MultiIndexSelector
+ from narwhals.dtypes import DType
+ from narwhals.typing import (
+ IntoDType,
+ IntoExpr,
+ IntoFrame,
+ IntoSeries,
+ NonNestedLiteral,
+ SingleColSelector,
+ SingleIndexSelector,
+ _1DArray,
+ _2DArray,
+ )
+
+ DataFrameT = TypeVar("DataFrameT", bound="DataFrame[Any]")
+ LazyFrameT = TypeVar("LazyFrameT", bound="LazyFrame[Any]")
+ SeriesT = TypeVar("SeriesT", bound="Series[Any]")
+ T = TypeVar("T", default=Any)
+ P = ParamSpec("P")
+ R = TypeVar("R")
+
+IntoSeriesT = TypeVar("IntoSeriesT", bound="IntoSeries", default=Any)
+
+
+class DataFrame(NwDataFrame[IntoDataFrameT]):
+ @inherit_doc(NwDataFrame)
+ def __init__(self, df: Any, *, level: Literal["full", "lazy", "interchange"]) -> None:
+ assert df._version is Version.V2 # noqa: S101
+ super().__init__(df, level=level)
+
+ # We need to override any method which don't return Self so that type
+ # annotations are correct.
+
+ @property
+ def _series(self) -> type[Series[Any]]:
+ return cast("type[Series[Any]]", Series)
+
+ @property
+ def _lazyframe(self) -> type[LazyFrame[Any]]:
+ return cast("type[LazyFrame[Any]]", LazyFrame)
+
+ @overload
+ def __getitem__(self, item: tuple[SingleIndexSelector, SingleColSelector]) -> Any: ...
+
+ @overload
+ def __getitem__( # type: ignore[overload-overlap]
+ self, item: str | tuple[MultiIndexSelector, SingleColSelector]
+ ) -> Series[Any]: ...
+
+ @overload
+ def __getitem__(
+ self,
+ item: (
+ SingleIndexSelector
+ | MultiIndexSelector
+ | MultiColSelector
+ | tuple[SingleIndexSelector, MultiColSelector]
+ | tuple[MultiIndexSelector, MultiColSelector]
+ ),
+ ) -> Self: ...
+ def __getitem__(
+ self,
+ item: (
+ SingleIndexSelector
+ | SingleColSelector
+ | MultiColSelector
+ | MultiIndexSelector
+ | tuple[SingleIndexSelector, SingleColSelector]
+ | tuple[SingleIndexSelector, MultiColSelector]
+ | tuple[MultiIndexSelector, SingleColSelector]
+ | tuple[MultiIndexSelector, MultiColSelector]
+ ),
+ ) -> Series[Any] | Self | Any:
+ return super().__getitem__(item)
+
+ def get_column(self, name: str) -> Series:
+ # Type checkers complain that `nw.Series` is not assignable to `nw.v2.stable.Series`.
+ # However the return type actually is `nw.v2.stable.Series`, check `tests/v2_test.py`.
+ return super().get_column(name) # type: ignore[return-value]
+
+ def lazy(
+ self, backend: ModuleType | Implementation | str | None = None
+ ) -> LazyFrame[Any]:
+ return _stableify(super().lazy(backend=backend))
+
+ @overload # type: ignore[override]
+ def to_dict(self, *, as_series: Literal[True] = ...) -> dict[str, Series[Any]]: ...
+ @overload
+ def to_dict(self, *, as_series: Literal[False]) -> dict[str, list[Any]]: ...
+ @overload
+ def to_dict(
+ self, *, as_series: bool
+ ) -> dict[str, Series[Any]] | dict[str, list[Any]]: ...
+ def to_dict(
+ self, *, as_series: bool = True
+ ) -> dict[str, Series[Any]] | dict[str, list[Any]]:
+ # Type checkers complain that `nw.Series` is not assignable to `nw.v2.stable.Series`.
+ # However the return type actually is `nw.v2.stable.Series`, check `tests/v2_test.py::test_to_dict_as_series`.
+ return super().to_dict(as_series=as_series) # type: ignore[return-value]
+
+ def is_duplicated(self) -> Series[Any]:
+ return _stableify(super().is_duplicated())
+
+ def is_unique(self) -> Series[Any]:
+ return _stableify(super().is_unique())
+
+
+class LazyFrame(NwLazyFrame[IntoFrameT]):
+ @inherit_doc(NwLazyFrame)
+ def __init__(self, df: Any, *, level: Literal["full", "lazy", "interchange"]) -> None:
+ assert df._version is Version.V2 # noqa: S101
+ super().__init__(df, level=level)
+
+ @property
+ def _dataframe(self) -> type[DataFrame[Any]]:
+ return DataFrame
+
+ def collect(
+ self, backend: ModuleType | Implementation | str | None = None, **kwargs: Any
+ ) -> DataFrame[Any]:
+ return _stableify(super().collect(backend=backend, **kwargs))
+
+
+class Series(NwSeries[IntoSeriesT]):
+ @inherit_doc(NwSeries)
+ def __init__(
+ self, series: Any, *, level: Literal["full", "lazy", "interchange"]
+ ) -> None:
+ assert series._version is Version.V2 # noqa: S101
+ super().__init__(series, level=level)
+
+ # We need to override any method which don't return Self so that type
+ # annotations are correct.
+
+ @property
+ def _dataframe(self) -> type[DataFrame[Any]]:
+ return DataFrame
+
+ def to_frame(self) -> DataFrame[Any]:
+ return _stableify(super().to_frame())
+
+ def value_counts(
+ self,
+ *,
+ sort: bool = False,
+ parallel: bool = False,
+ name: str | None = None,
+ normalize: bool = False,
+ ) -> DataFrame[Any]:
+ return _stableify(
+ super().value_counts(
+ sort=sort, parallel=parallel, name=name, normalize=normalize
+ )
+ )
+
+ # Too unstable to consider including here.
+ hist: Any = not_implemented()
+
+
+class Expr(NwExpr): ...
+
+
+class Schema(NwSchema):
+ _version = Version.V2
+
+ @inherit_doc(NwSchema)
+ def __init__(
+ self, schema: Mapping[str, DType] | Iterable[tuple[str, DType]] | None = None
+ ) -> None:
+ super().__init__(schema)
+
+
+@overload
+def _stableify(obj: NwDataFrame[IntoFrameT]) -> DataFrame[IntoFrameT]: ...
+@overload
+def _stableify(obj: NwLazyFrame[IntoFrameT]) -> LazyFrame[IntoFrameT]: ...
+@overload
+def _stableify(obj: NwSeries[IntoSeriesT]) -> Series[IntoSeriesT]: ...
+@overload
+def _stableify(obj: NwExpr) -> Expr: ...
+
+
+def _stableify(
+ obj: NwDataFrame[IntoFrameT]
+ | NwLazyFrame[IntoFrameT]
+ | NwSeries[IntoSeriesT]
+ | NwExpr,
+) -> DataFrame[IntoFrameT] | LazyFrame[IntoFrameT] | Series[IntoSeriesT] | Expr:
+ if isinstance(obj, NwDataFrame):
+ return DataFrame(obj._compliant_frame._with_version(Version.V2), level=obj._level)
+ if isinstance(obj, NwLazyFrame):
+ return LazyFrame(obj._compliant_frame._with_version(Version.V2), level=obj._level)
+ if isinstance(obj, NwSeries):
+ return Series(obj._compliant_series._with_version(Version.V2), level=obj._level)
+ if isinstance(obj, NwExpr):
+ return Expr(obj._to_compliant_expr, obj._metadata)
+ assert_never(obj)
+
+
+@overload
+def from_native(native_object: SeriesT, **kwds: Any) -> SeriesT: ...
+
+
+@overload
+def from_native(native_object: DataFrameT, **kwds: Any) -> DataFrameT: ...
+
+
+@overload
+def from_native(native_object: LazyFrameT, **kwds: Any) -> LazyFrameT: ...
+
+
+@overload
+def from_native(
+ native_object: DataFrameT | LazyFrameT, **kwds: Any
+) -> DataFrameT | LazyFrameT: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT | IntoSeries,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: Literal[True],
+) -> DataFrame[IntoDataFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT | IntoSeriesT,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[True],
+ series_only: Literal[False] = ...,
+ allow_series: Literal[True],
+) -> DataFrame[IntoDataFrameT] | Series[IntoSeriesT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> DataFrame[IntoDataFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: T,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> T: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[True],
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> DataFrame[IntoDataFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: T,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[True],
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> T: ...
+
+
+@overload
+def from_native(
+ native_object: IntoSeriesT,
+ *,
+ pass_through: Literal[True],
+ eager_only: Literal[False] = ...,
+ series_only: Literal[True],
+ allow_series: None = ...,
+) -> Series[IntoSeriesT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT,
+ *,
+ pass_through: Literal[False] = ...,
+ eager_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> DataFrame[IntoDataFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoDataFrameT,
+ *,
+ pass_through: Literal[False] = ...,
+ eager_only: Literal[True],
+ series_only: Literal[False] = ...,
+ allow_series: None = ...,
+) -> DataFrame[IntoDataFrameT]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoFrame | IntoSeries,
+ *,
+ pass_through: Literal[False] = ...,
+ eager_only: Literal[False] = ...,
+ series_only: Literal[False] = ...,
+ allow_series: Literal[True],
+) -> DataFrame[Any] | LazyFrame[Any] | Series[Any]: ...
+
+
+@overload
+def from_native(
+ native_object: IntoSeriesT,
+ *,
+ pass_through: Literal[False] = ...,
+ eager_only: Literal[False] = ...,
+ series_only: Literal[True],
+ allow_series: None = ...,
+) -> Series[IntoSeriesT]: ...
+
+
+# All params passed in as variables
+@overload
+def from_native(
+ native_object: Any,
+ *,
+ pass_through: bool,
+ eager_only: bool,
+ series_only: bool,
+ allow_series: bool | None,
+) -> Any: ...
+
+
+def from_native( # noqa: D417
+ native_object: IntoFrameT | IntoFrame | IntoSeriesT | IntoSeries | T,
+ *,
+ pass_through: bool = False,
+ eager_only: bool = False,
+ series_only: bool = False,
+ allow_series: bool | None = None,
+ **kwds: Any,
+) -> LazyFrame[IntoFrameT] | DataFrame[IntoFrameT] | Series[IntoSeriesT] | T:
+ """Convert `native_object` to Narwhals Dataframe, Lazyframe, or Series.
+
+ Arguments:
+ native_object: Raw object from user.
+ Depending on the other arguments, input object can be
+
+ - a Dataframe / Lazyframe / Series supported by Narwhals (pandas, Polars, PyArrow, ...)
+ - an object which implements `__narwhals_dataframe__`, `__narwhals_lazyframe__`,
+ or `__narwhals_series__`
+ pass_through: Determine what happens if the object can't be converted to Narwhals
+
+ - `False` (default): raise an error
+ - `True`: pass object through as-is
+ eager_only: Whether to only allow eager objects
+
+ - `False` (default): don't require `native_object` to be eager
+ - `True`: only convert to Narwhals if `native_object` is eager
+ series_only: Whether to only allow Series
+
+ - `False` (default): don't require `native_object` to be a Series
+ - `True`: only convert to Narwhals if `native_object` is a Series
+ allow_series: Whether to allow Series (default is only Dataframe / Lazyframe)
+
+ - `False` or `None` (default): don't convert to Narwhals if `native_object` is a Series
+ - `True`: allow `native_object` to be a Series
+
+ Returns:
+ DataFrame, LazyFrame, Series, or original object, depending
+ on which combination of parameters was passed.
+ """
+ # Early returns
+ if isinstance(native_object, (DataFrame, LazyFrame)) and not series_only:
+ return native_object
+ if isinstance(native_object, Series) and (series_only or allow_series):
+ return native_object
+
+ if kwds:
+ msg = f"from_native() got an unexpected keyword argument {next(iter(kwds))!r}"
+ raise TypeError(msg)
+
+ return _from_native_impl( # type: ignore[no-any-return]
+ native_object,
+ pass_through=pass_through,
+ eager_only=eager_only,
+ series_only=series_only,
+ allow_series=allow_series,
+ version=Version.V2,
+ )
+
+
+@overload
+def to_native(
+ narwhals_object: DataFrame[IntoDataFrameT], *, pass_through: Literal[False] = ...
+) -> IntoDataFrameT: ...
+@overload
+def to_native(
+ narwhals_object: LazyFrame[IntoFrameT], *, pass_through: Literal[False] = ...
+) -> IntoFrameT: ...
+@overload
+def to_native(
+ narwhals_object: Series[IntoSeriesT], *, pass_through: Literal[False] = ...
+) -> IntoSeriesT: ...
+@overload
+def to_native(narwhals_object: Any, *, pass_through: bool) -> Any: ...
+
+
+def to_native(
+ narwhals_object: DataFrame[IntoDataFrameT]
+ | LazyFrame[IntoFrameT]
+ | Series[IntoSeriesT],
+ *,
+ pass_through: bool = False,
+) -> IntoFrameT | IntoSeriesT | Any:
+ """Convert Narwhals object to native one.
+
+ Arguments:
+ narwhals_object: Narwhals object.
+ pass_through: Determine what happens if `narwhals_object` isn't a Narwhals class
+
+ - `False` (default): raise an error
+ - `True`: pass object through as-is
+
+ Returns:
+ Object of class that user started with.
+ """
+ return nw.to_native(narwhals_object, pass_through=pass_through)
+
+
+def narwhalify(
+ func: Callable[..., Any] | None = None,
+ *,
+ pass_through: bool = True,
+ eager_only: bool = False,
+ series_only: bool = False,
+ allow_series: bool | None = True,
+) -> Callable[..., Any]:
+ """Decorate function so it becomes dataframe-agnostic.
+
+ This will try to convert any dataframe/series-like object into the Narwhals
+ respective DataFrame/Series, while leaving the other parameters as they are.
+ Similarly, if the output of the function is a Narwhals DataFrame or Series, it will be
+ converted back to the original dataframe/series type, while if the output is another
+ type it will be left as is.
+ By setting `pass_through=False`, then every input and every output will be required to be a
+ dataframe/series-like object.
+
+ Arguments:
+ func: Function to wrap in a `from_native`-`to_native` block.
+ pass_through: Determine what happens if the object can't be converted to Narwhals
+
+ - `False`: raise an error
+ - `True` (default): pass object through as-is
+ eager_only: Whether to only allow eager objects
+
+ - `False` (default): don't require `native_object` to be eager
+ - `True`: only convert to Narwhals if `native_object` is eager
+ series_only: Whether to only allow Series
+
+ - `False` (default): don't require `native_object` to be a Series
+ - `True`: only convert to Narwhals if `native_object` is a Series
+ allow_series: Whether to allow Series (default is only Dataframe / Lazyframe)
+
+ - `False` or `None`: don't convert to Narwhals if `native_object` is a Series
+ - `True` (default): allow `native_object` to be a Series
+
+ Returns:
+ Decorated function.
+ """
+
+ def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
+ @wraps(func)
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
+ args = [
+ from_native(
+ arg,
+ pass_through=pass_through,
+ eager_only=eager_only,
+ series_only=series_only,
+ allow_series=allow_series,
+ )
+ for arg in args
+ ] # type: ignore[assignment]
+
+ kwargs = {
+ name: from_native(
+ value,
+ pass_through=pass_through,
+ eager_only=eager_only,
+ series_only=series_only,
+ allow_series=allow_series,
+ )
+ for name, value in kwargs.items()
+ }
+
+ backends = {
+ b()
+ for v in (*args, *kwargs.values())
+ if (b := getattr(v, "__native_namespace__", None))
+ }
+
+ if backends.__len__() > 1:
+ msg = "Found multiple backends. Make sure that all dataframe/series inputs come from the same backend."
+ raise ValueError(msg)
+
+ result = func(*args, **kwargs)
+
+ return to_native(result, pass_through=pass_through)
+
+ return wrapper
+
+ if func is None:
+ return decorator
+ else:
+ # If func is not None, it means the decorator is used without arguments
+ return decorator(func)
+
+
+def all() -> Expr:
+ """Instantiate an expression representing all columns.
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.all())
+
+
+def col(*names: str | Iterable[str]) -> Expr:
+ """Creates an expression that references one or more columns by their name(s).
+
+ Arguments:
+ names: Name(s) of the columns to use.
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.col(*names))
+
+
+def exclude(*names: str | Iterable[str]) -> Expr:
+ """Creates an expression that excludes columns by their name(s).
+
+ Arguments:
+ names: Name(s) of the columns to exclude.
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.exclude(*names))
+
+
+def nth(*indices: int | Sequence[int]) -> Expr:
+ """Creates an expression that references one or more columns by their index(es).
+
+ Notes:
+ `nth` is not supported for Polars version<1.0.0. Please use
+ [`narwhals.col`][] instead.
+
+ Arguments:
+ indices: One or more indices representing the columns to retrieve.
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.nth(*indices))
+
+
+def len() -> Expr:
+ """Return the number of rows.
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.len())
+
+
+def lit(value: NonNestedLiteral, dtype: IntoDType | None = None) -> Expr:
+ """Return an expression representing a literal value.
+
+ Arguments:
+ value: The value to use as literal.
+ dtype: The data type of the literal value. If not provided, the data type will
+ be inferred by the native library.
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.lit(value, dtype))
+
+
+def min(*columns: str) -> Expr:
+ """Return the minimum value.
+
+ Note:
+ Syntactic sugar for ``nw.col(columns).min()``.
+
+ Arguments:
+ columns: Name(s) of the columns to use in the aggregation function.
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.min(*columns))
+
+
+def max(*columns: str) -> Expr:
+ """Return the maximum value.
+
+ Note:
+ Syntactic sugar for ``nw.col(columns).max()``.
+
+ Arguments:
+ columns: Name(s) of the columns to use in the aggregation function.
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.max(*columns))
+
+
+def mean(*columns: str) -> Expr:
+ """Get the mean value.
+
+ Note:
+ Syntactic sugar for ``nw.col(columns).mean()``
+
+ Arguments:
+ columns: Name(s) of the columns to use in the aggregation function
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.mean(*columns))
+
+
+def median(*columns: str) -> Expr:
+ """Get the median value.
+
+ Notes:
+ - Syntactic sugar for ``nw.col(columns).median()``
+ - Results might slightly differ across backends due to differences in the
+ underlying algorithms used to compute the median.
+
+ Arguments:
+ columns: Name(s) of the columns to use in the aggregation function
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.median(*columns))
+
+
+def sum(*columns: str) -> Expr:
+ """Sum all values.
+
+ Note:
+ Syntactic sugar for ``nw.col(columns).sum()``
+
+ Arguments:
+ columns: Name(s) of the columns to use in the aggregation function
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.sum(*columns))
+
+
+def sum_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
+ """Sum all values horizontally across columns.
+
+ Warning:
+ Unlike Polars, we support horizontal sum over numeric columns only.
+
+ Arguments:
+ exprs: Name(s) of the columns to use in the aggregation function. Accepts
+ expression input.
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.sum_horizontal(*exprs))
+
+
+def all_horizontal(*exprs: IntoExpr | Iterable[IntoExpr], ignore_nulls: bool) -> Expr:
+ r"""Compute the bitwise AND horizontally across columns.
+
+ Arguments:
+ exprs: Name(s) of the columns to use in the aggregation function. Accepts
+ expression input.
+ ignore_nulls: Whether to ignore nulls:
+
+ - If `True`, null values are ignored. If there are no elements, the result
+ is `True`.
+ - If `False`, Kleene logic is followed. Note that this is not allowed for
+ pandas with classical NumPy dtypes when null values are present.
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.all_horizontal(*exprs, ignore_nulls=ignore_nulls))
+
+
+def any_horizontal(*exprs: IntoExpr | Iterable[IntoExpr], ignore_nulls: bool) -> Expr:
+ r"""Compute the bitwise OR horizontally across columns.
+
+ Arguments:
+ exprs: Name(s) of the columns to use in the aggregation function. Accepts
+ expression input.
+ ignore_nulls: Whether to ignore nulls:
+
+ - If `True`, null values are ignored. If there are no elements, the result
+ is `False`.
+ - If `False`, Kleene logic is followed. Note that this is not allowed for
+ pandas with classical NumPy dtypes when null values are present.
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.any_horizontal(*exprs, ignore_nulls=ignore_nulls))
+
+
+def mean_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
+ """Compute the mean of all values horizontally across columns.
+
+ Arguments:
+ exprs: Name(s) of the columns to use in the aggregation function. Accepts
+ expression input.
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.mean_horizontal(*exprs))
+
+
+def min_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
+ """Get the minimum value horizontally across columns.
+
+ Notes:
+ We support `min_horizontal` over numeric columns only.
+
+ Arguments:
+ exprs: Name(s) of the columns to use in the aggregation function. Accepts
+ expression input.
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.min_horizontal(*exprs))
+
+
+def max_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
+ """Get the maximum value horizontally across columns.
+
+ Notes:
+ We support `max_horizontal` over numeric columns only.
+
+ Arguments:
+ exprs: Name(s) of the columns to use in the aggregation function. Accepts
+ expression input.
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.max_horizontal(*exprs))
+
+
+def concat_str(
+ exprs: IntoExpr | Iterable[IntoExpr],
+ *more_exprs: IntoExpr,
+ separator: str = "",
+ ignore_nulls: bool = False,
+) -> Expr:
+ r"""Horizontally concatenate columns into a single string column.
+
+ Arguments:
+ exprs: Columns to concatenate into a single string column. Accepts expression
+ input. Strings are parsed as column names, other non-expression inputs are
+ parsed as literals. Non-`String` columns are cast to `String`.
+ *more_exprs: Additional columns to concatenate into a single string column,
+ specified as positional arguments.
+ separator: String that will be used to separate the values of each column.
+ ignore_nulls: Ignore null values (default is `False`).
+ If set to `False`, null values will be propagated and if the row contains any
+ null values, the output is null.
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(
+ nw.concat_str(exprs, *more_exprs, separator=separator, ignore_nulls=ignore_nulls)
+ )
+
+
+def coalesce(exprs: IntoExpr | Iterable[IntoExpr], *more_exprs: IntoExpr) -> Expr:
+ """Folds the columns from left to right, keeping the first non-null value.
+
+ Arguments:
+ exprs: Columns to coalesce, must be a str, nw.Expr, or nw.Series
+ where strings are parsed as column names and both nw.Expr/nw.Series
+ are passed through as-is. Scalar values must be wrapped in `nw.lit`.
+
+ *more_exprs: Additional columns to coalesce, specified as positional arguments.
+
+ Raises:
+ TypeError: If any of the inputs are not a str, nw.Expr, or nw.Series.
+
+ Returns:
+ A new expression.
+ """
+ return _stableify(nw.coalesce(exprs, *more_exprs))
+
+
+class When(nw_f.When):
+ @classmethod
+ def from_when(cls, when: nw_f.When) -> When:
+ return cls(when._predicate)
+
+ def then(self, value: IntoExpr | NonNestedLiteral | _1DArray) -> Then:
+ return Then.from_then(super().then(value))
+
+
+class Then(nw_f.Then, Expr):
+ @classmethod
+ def from_then(cls, then: nw_f.Then) -> Then:
+ return cls(then._to_compliant_expr, then._metadata)
+
+ def otherwise(self, value: IntoExpr | NonNestedLiteral | _1DArray) -> Expr:
+ return _stableify(super().otherwise(value))
+
+
+def when(*predicates: IntoExpr | Iterable[IntoExpr]) -> When:
+ """Start a `when-then-otherwise` expression.
+
+ Expression similar to an `if-else` statement in Python. Always initiated by a
+ `pl.when().then()`, and optionally followed by a
+ `.otherwise()` can be appended at the end. If not
+ appended, and the condition is not `True`, `None` will be returned.
+
+ Info:
+ Chaining multiple `.when().then()` statements is currently
+ not supported.
+ See [Narwhals#668](https://github.com/narwhals-dev/narwhals/issues/668).
+
+ Arguments:
+ predicates: Condition(s) that must be met in order to apply the subsequent
+ statement. Accepts one or more boolean expressions, which are implicitly
+ combined with `&`. String input is parsed as a column name.
+
+ Returns:
+ A "when" object, which `.then` can be called on.
+ """
+ return When.from_when(nw_f.when(*predicates))
+
+
+def new_series(
+ name: str,
+ values: Any,
+ dtype: IntoDType | None = None,
+ *,
+ backend: ModuleType | Implementation | str,
+) -> Series[Any]:
+ """Instantiate Narwhals Series from iterable (e.g. list or array).
+
+ Arguments:
+ name: Name of resulting Series.
+ values: Values of make Series from.
+ dtype: (Narwhals) dtype. If not provided, the native library
+ may auto-infer it from `values`.
+ backend: specifies which eager backend instantiate to.
+
+ `backend` can be specified in various ways
+
+ - As `Implementation.` with `BACKEND` being `PANDAS`, `PYARROW`,
+ `POLARS`, `MODIN` or `CUDF`.
+ - As a string: `"pandas"`, `"pyarrow"`, `"polars"`, `"modin"` or `"cudf"`.
+ - Directly as a module `pandas`, `pyarrow`, `polars`, `modin` or `cudf`.
+
+ Returns:
+ A new Series
+ """
+ return _stableify(_new_series_impl(name, values, dtype, backend=backend))
+
+
+def from_arrow(
+ native_frame: IntoArrowTable, *, backend: ModuleType | Implementation | str
+) -> DataFrame[Any]:
+ """Construct a DataFrame from an object which supports the PyCapsule Interface.
+
+ Arguments:
+ native_frame: Object which implements `__arrow_c_stream__`.
+ backend: specifies which eager backend instantiate to.
+
+ `backend` can be specified in various ways
+
+ - As `Implementation.` with `BACKEND` being `PANDAS`, `PYARROW`,
+ `POLARS`, `MODIN` or `CUDF`.
+ - As a string: `"pandas"`, `"pyarrow"`, `"polars"`, `"modin"` or `"cudf"`.
+ - Directly as a module `pandas`, `pyarrow`, `polars`, `modin` or `cudf`.
+
+ Returns:
+ A new DataFrame.
+ """
+ return _stableify(nw_f.from_arrow(native_frame, backend=backend))
+
+
+def from_dict(
+ data: Mapping[str, Any],
+ schema: Mapping[str, DType] | Schema | None = None,
+ *,
+ backend: ModuleType | Implementation | str | None = None,
+) -> DataFrame[Any]:
+ """Instantiate DataFrame from dictionary.
+
+ Indexes (if present, for pandas-like backends) are aligned following
+ the [left-hand-rule](../concepts/pandas_index.md/).
+
+ Notes:
+ For pandas-like dataframes, conversion to schema is applied after dataframe
+ creation.
+
+ Arguments:
+ data: Dictionary to create DataFrame from.
+ schema: The DataFrame schema as Schema or dict of {name: type}. If not
+ specified, the schema will be inferred by the native library.
+ backend: specifies which eager backend instantiate to. Only
+ necessary if inputs are not Narwhals Series.
+
+ `backend` can be specified in various ways
+
+ - As `Implementation.` with `BACKEND` being `PANDAS`, `PYARROW`,
+ `POLARS`, `MODIN` or `CUDF`.
+ - As a string: `"pandas"`, `"pyarrow"`, `"polars"`, `"modin"` or `"cudf"`.
+ - Directly as a module `pandas`, `pyarrow`, `polars`, `modin` or `cudf`.
+
+ Returns:
+ A new DataFrame.
+ """
+ return _stableify(nw_f.from_dict(data, schema, backend=backend))
+
+
+def from_numpy(
+ data: _2DArray,
+ schema: Mapping[str, DType] | Schema | Sequence[str] | None = None,
+ *,
+ backend: ModuleType | Implementation | str,
+) -> DataFrame[Any]:
+ """Construct a DataFrame from a NumPy ndarray.
+
+ Notes:
+ Only row orientation is currently supported.
+
+ For pandas-like dataframes, conversion to schema is applied after dataframe
+ creation.
+
+ Arguments:
+ data: Two-dimensional data represented as a NumPy ndarray.
+ schema: The DataFrame schema as Schema, dict of {name: type}, or a sequence of str.
+ backend: specifies which eager backend instantiate to.
+
+ `backend` can be specified in various ways
+
+ - As `Implementation.` with `BACKEND` being `PANDAS`, `PYARROW`,
+ `POLARS`, `MODIN` or `CUDF`.
+ - As a string: `"pandas"`, `"pyarrow"`, `"polars"`, `"modin"` or `"cudf"`.
+ - Directly as a module `pandas`, `pyarrow`, `polars`, `modin` or `cudf`.
+
+ Returns:
+ A new DataFrame.
+ """
+ return _stableify(nw_f.from_numpy(data, schema, backend=backend))
+
+
+def read_csv(
+ source: str, *, backend: ModuleType | Implementation | str, **kwargs: Any
+) -> DataFrame[Any]:
+ """Read a CSV file into a DataFrame.
+
+ Arguments:
+ source: Path to a file.
+ backend: The eager backend for DataFrame creation.
+ `backend` can be specified in various ways
+
+ - As `Implementation.` with `BACKEND` being `PANDAS`, `PYARROW`,
+ `POLARS`, `MODIN` or `CUDF`.
+ - As a string: `"pandas"`, `"pyarrow"`, `"polars"`, `"modin"` or `"cudf"`.
+ - Directly as a module `pandas`, `pyarrow`, `polars`, `modin` or `cudf`.
+ kwargs: Extra keyword arguments which are passed to the native CSV reader.
+ For example, you could use
+ `nw.read_csv('file.csv', backend='pandas', engine='pyarrow')`.
+
+ Returns:
+ DataFrame.
+ """
+ return _stableify(nw_f.read_csv(source, backend=backend, **kwargs))
+
+
+def scan_csv(
+ source: str, *, backend: ModuleType | Implementation | str, **kwargs: Any
+) -> LazyFrame[Any]:
+ """Lazily read from a CSV file.
+
+ For the libraries that do not support lazy dataframes, the function reads
+ a csv file eagerly and then converts the resulting dataframe to a lazyframe.
+
+ Arguments:
+ source: Path to a file.
+ backend: The eager backend for DataFrame creation.
+ `backend` can be specified in various ways
+
+ - As `Implementation.` with `BACKEND` being `PANDAS`, `PYARROW`,
+ `POLARS`, `MODIN` or `CUDF`.
+ - As a string: `"pandas"`, `"pyarrow"`, `"polars"`, `"modin"` or `"cudf"`.
+ - Directly as a module `pandas`, `pyarrow`, `polars`, `modin` or `cudf`.
+ kwargs: Extra keyword arguments which are passed to the native CSV reader.
+ For example, you could use
+ `nw.scan_csv('file.csv', backend=pd, engine='pyarrow')`.
+
+ Returns:
+ LazyFrame.
+ """
+ return _stableify(nw_f.scan_csv(source, backend=backend, **kwargs))
+
+
+def read_parquet(
+ source: str, *, backend: ModuleType | Implementation | str, **kwargs: Any
+) -> DataFrame[Any]:
+ """Read into a DataFrame from a parquet file.
+
+ Arguments:
+ source: Path to a file.
+ backend: The eager backend for DataFrame creation.
+ `backend` can be specified in various ways
+
+ - As `Implementation.` with `BACKEND` being `PANDAS`, `PYARROW`,
+ `POLARS`, `MODIN` or `CUDF`.
+ - As a string: `"pandas"`, `"pyarrow"`, `"polars"`, `"modin"` or `"cudf"`.
+ - Directly as a module `pandas`, `pyarrow`, `polars`, `modin` or `cudf`.
+ kwargs: Extra keyword arguments which are passed to the native parquet reader.
+ For example, you could use
+ `nw.read_parquet('file.parquet', backend=pd, engine='pyarrow')`.
+
+ Returns:
+ DataFrame.
+ """
+ return _stableify(nw_f.read_parquet(source, backend=backend, **kwargs))
+
+
+def scan_parquet(
+ source: str, *, backend: ModuleType | Implementation | str, **kwargs: Any
+) -> LazyFrame[Any]:
+ """Lazily read from a parquet file.
+
+ For the libraries that do not support lazy dataframes, the function reads
+ a parquet file eagerly and then converts the resulting dataframe to a lazyframe.
+
+ Note:
+ Spark like backends require a session object to be passed in `kwargs`.
+
+ For instance:
+
+ ```py
+ import narwhals as nw
+ from sqlframe.duckdb import DuckDBSession
+
+ nw.scan_parquet(source, backend="sqlframe", session=DuckDBSession())
+ ```
+
+ Arguments:
+ source: Path to a file.
+ backend: The eager backend for DataFrame creation.
+ `backend` can be specified in various ways
+
+ - As `Implementation.` with `BACKEND` being `PANDAS`, `PYARROW`,
+ `POLARS`, `MODIN`, `CUDF`, `PYSPARK` or `SQLFRAME`.
+ - As a string: `"pandas"`, `"pyarrow"`, `"polars"`, `"modin"`, `"cudf"`,
+ `"pyspark"` or `"sqlframe"`.
+ - Directly as a module `pandas`, `pyarrow`, `polars`, `modin`, `cudf`,
+ `pyspark.sql` or `sqlframe`.
+ kwargs: Extra keyword arguments which are passed to the native parquet reader.
+ For example, you could use
+ `nw.scan_parquet('file.parquet', backend=pd, engine='pyarrow')`.
+
+ Returns:
+ LazyFrame.
+ """
+ return _stableify(nw_f.scan_parquet(source, backend=backend, **kwargs))
+
+
+__all__ = [
+ "Array",
+ "Binary",
+ "Boolean",
+ "Categorical",
+ "DataFrame",
+ "Date",
+ "Datetime",
+ "Decimal",
+ "Duration",
+ "Enum",
+ "Expr",
+ "Field",
+ "Float32",
+ "Float64",
+ "Implementation",
+ "Int8",
+ "Int16",
+ "Int32",
+ "Int64",
+ "Int128",
+ "LazyFrame",
+ "List",
+ "Object",
+ "Schema",
+ "Series",
+ "String",
+ "Struct",
+ "Time",
+ "UInt8",
+ "UInt16",
+ "UInt32",
+ "UInt64",
+ "UInt128",
+ "Unknown",
+ "all",
+ "all_horizontal",
+ "any_horizontal",
+ "coalesce",
+ "col",
+ "concat",
+ "concat_str",
+ "dependencies",
+ "dtypes",
+ "dtypes",
+ "exceptions",
+ "exclude",
+ "from_arrow",
+ "from_dict",
+ "from_native",
+ "from_numpy",
+ "generate_temporary_column_name",
+ "get_native_namespace",
+ "is_ordered_categorical",
+ "len",
+ "lit",
+ "max",
+ "max_horizontal",
+ "maybe_align_index",
+ "maybe_convert_dtypes",
+ "maybe_get_index",
+ "maybe_reset_index",
+ "maybe_set_index",
+ "mean",
+ "mean_horizontal",
+ "median",
+ "min",
+ "min_horizontal",
+ "narwhalify",
+ "new_series",
+ "nth",
+ "read_csv",
+ "read_parquet",
+ "scan_csv",
+ "scan_parquet",
+ "selectors",
+ "selectors",
+ "show_versions",
+ "sum",
+ "sum_horizontal",
+ "to_native",
+ "to_py_scalar",
+ "when",
+]
diff --git a/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/__init__.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3ac796b5e878e66d8c9b5b1ff9597d5651f169af
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/__init__.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/_namespace.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/_namespace.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b9023b91dde28273f76125ac5c5a33bbe3272711
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/_namespace.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/dependencies.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/dependencies.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..12ff722f0d6dfcfdfaadae8ea051878befe2fd44
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/dependencies.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/dtypes.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/dtypes.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..dd494216ed2e9a2037029336aaeb596ff7ccd569
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/dtypes.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/selectors.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/selectors.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..551a9fec5bac7ea809e0f9fa62eaff3f4fb647c3
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/selectors.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/typing.cpython-310.pyc b/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/typing.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ac73ce2f494be808a1098971bfe1879e031f3eb3
Binary files /dev/null and b/lib/python3.10/site-packages/narwhals/stable/v2/__pycache__/typing.cpython-310.pyc differ
diff --git a/lib/python3.10/site-packages/narwhals/stable/v2/_namespace.py b/lib/python3.10/site-packages/narwhals/stable/v2/_namespace.py
new file mode 100644
index 0000000000000000000000000000000000000000..b30093cc6c339729b5d6f49b46515e1b1525c3f8
--- /dev/null
+++ b/lib/python3.10/site-packages/narwhals/stable/v2/_namespace.py
@@ -0,0 +1,10 @@
+from __future__ import annotations
+
+from narwhals._compliant.typing import CompliantNamespaceT_co
+from narwhals._namespace import Namespace as NwNamespace
+from narwhals._utils import Version
+
+__all__ = ["Namespace"]
+
+
+class Namespace(NwNamespace[CompliantNamespaceT_co], version=Version.V2): ...
diff --git a/lib/python3.10/site-packages/narwhals/stable/v2/dependencies.py b/lib/python3.10/site-packages/narwhals/stable/v2/dependencies.py
new file mode 100644
index 0000000000000000000000000000000000000000..09dac9689283f5d30c56ad71bfadbba8cc811103
--- /dev/null
+++ b/lib/python3.10/site-packages/narwhals/stable/v2/dependencies.py
@@ -0,0 +1,3 @@
+from __future__ import annotations
+
+from narwhals.dependencies import * # noqa: F403
diff --git a/lib/python3.10/site-packages/narwhals/stable/v2/dtypes.py b/lib/python3.10/site-packages/narwhals/stable/v2/dtypes.py
new file mode 100644
index 0000000000000000000000000000000000000000..b2d9cb0a21f6a1c0cb469b9aebc188cb844f171f
--- /dev/null
+++ b/lib/python3.10/site-packages/narwhals/stable/v2/dtypes.py
@@ -0,0 +1,3 @@
+from __future__ import annotations
+
+from narwhals.dtypes import * # noqa: F403
diff --git a/lib/python3.10/site-packages/narwhals/stable/v2/selectors.py b/lib/python3.10/site-packages/narwhals/stable/v2/selectors.py
new file mode 100644
index 0000000000000000000000000000000000000000..79089a2761adc27d790f6cc108255875189591be
--- /dev/null
+++ b/lib/python3.10/site-packages/narwhals/stable/v2/selectors.py
@@ -0,0 +1,3 @@
+from __future__ import annotations
+
+from narwhals.selectors import * # noqa: F403
diff --git a/lib/python3.10/site-packages/narwhals/stable/v2/typing.py b/lib/python3.10/site-packages/narwhals/stable/v2/typing.py
new file mode 100644
index 0000000000000000000000000000000000000000..16d42804c2263ea659adb58dd28d2f1c53fb37c9
--- /dev/null
+++ b/lib/python3.10/site-packages/narwhals/stable/v2/typing.py
@@ -0,0 +1,178 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any, Protocol, TypeVar, Union
+
+if TYPE_CHECKING:
+ import sys
+
+ from narwhals.stable.v2 import DataFrame, LazyFrame
+
+ if sys.version_info >= (3, 10):
+ from typing import TypeAlias
+ else:
+ from typing_extensions import TypeAlias
+
+ from narwhals.stable.v2 import Expr, Series
+
+ # All dataframes supported by Narwhals have a
+ # `columns` property. Their similarities don't extend
+ # _that_ much further unfortunately...
+ class NativeFrame(Protocol):
+ @property
+ def columns(self) -> Any: ...
+
+ def join(self, *args: Any, **kwargs: Any) -> Any: ...
+
+ class NativeSeries(Protocol):
+ def __len__(self) -> int: ...
+
+
+IntoExpr: TypeAlias = Union["Expr", str, "Series[Any]"]
+"""Anything which can be converted to an expression.
+
+Use this to mean "either a Narwhals expression, or something
+which can be converted into one". For example, `exprs` in `DataFrame.select` is
+typed to accept `IntoExpr`, as it can either accept a `nw.Expr`
+(e.g. `df.select(nw.col('a'))`) or a string which will be interpreted as a
+`nw.Expr`, e.g. `df.select('a')`.
+"""
+
+IntoDataFrame: TypeAlias = Union["NativeFrame", "DataFrame[Any]"]
+"""Anything which can be converted to a Narwhals DataFrame.
+
+Use this if your function accepts a narwhalifiable object but doesn't care about its backend.
+
+Examples:
+ >>> import narwhals as nw
+ >>> from narwhals.typing import IntoDataFrame
+ >>> def agnostic_shape(df_native: IntoDataFrame) -> tuple[int, int]:
+ ... df = nw.from_native(df_native, eager_only=True)
+ ... return df.shape
+"""
+
+IntoFrame: TypeAlias = Union["NativeFrame", "DataFrame[Any]", "LazyFrame[Any]"]
+"""Anything which can be converted to a Narwhals DataFrame or LazyFrame.
+
+Use this if your function can accept an object which can be converted to either
+`nw.DataFrame` or `nw.LazyFrame` and it doesn't care about its backend.
+
+Examples:
+ >>> import narwhals as nw
+ >>> from narwhals.typing import IntoFrame
+ >>> def agnostic_columns(df_native: IntoFrame) -> list[str]:
+ ... df = nw.from_native(df_native)
+ ... return df.collect_schema().names()
+"""
+
+Frame: TypeAlias = Union["DataFrame[Any]", "LazyFrame[Any]"]
+"""Narwhals DataFrame or Narwhals LazyFrame.
+
+Use this if your function can work with either and your function doesn't care
+about its backend.
+
+Examples:
+ >>> import narwhals as nw
+ >>> from narwhals.typing import Frame
+ >>> @nw.narwhalify
+ ... def agnostic_columns(df: Frame) -> list[str]:
+ ... return df.columns
+"""
+
+IntoSeries: TypeAlias = Union["Series[Any]", "NativeSeries"]
+"""Anything which can be converted to a Narwhals Series.
+
+Use this if your function can accept an object which can be converted to `nw.Series`
+and it doesn't care about its backend.
+
+Examples:
+ >>> from typing import Any
+ >>> import narwhals as nw
+ >>> from narwhals.typing import IntoSeries
+ >>> def agnostic_to_list(s_native: IntoSeries) -> list[Any]:
+ ... s = nw.from_native(s_native)
+ ... return s.to_list()
+"""
+
+IntoFrameT = TypeVar("IntoFrameT", bound="IntoFrame")
+"""TypeVar bound to object convertible to Narwhals DataFrame or Narwhals LazyFrame.
+
+Use this if your function accepts an object which is convertible to `nw.DataFrame`
+or `nw.LazyFrame` and returns an object of the same type.
+
+Examples:
+ >>> import narwhals as nw
+ >>> from narwhals.typing import IntoFrameT
+ >>> def agnostic_func(df_native: IntoFrameT) -> IntoFrameT:
+ ... df = nw.from_native(df_native)
+ ... return df.with_columns(c=nw.col("a") + 1).to_native()
+"""
+
+IntoDataFrameT = TypeVar("IntoDataFrameT", bound="IntoDataFrame")
+"""TypeVar bound to object convertible to Narwhals DataFrame.
+
+Use this if your function accepts an object which can be converted to `nw.DataFrame`
+and returns an object of the same class.
+
+Examples:
+ >>> import narwhals as nw
+ >>> from narwhals.typing import IntoDataFrameT
+ >>> def agnostic_func(df_native: IntoDataFrameT) -> IntoDataFrameT:
+ ... df = nw.from_native(df_native, eager_only=True)
+ ... return df.with_columns(c=df["a"] + 1).to_native()
+"""
+
+FrameT = TypeVar("FrameT", "DataFrame[Any]", "LazyFrame[Any]")
+"""TypeVar bound to Narwhals DataFrame or Narwhals LazyFrame.
+
+Use this if your function accepts either `nw.DataFrame` or `nw.LazyFrame` and returns
+an object of the same kind.
+
+Examples:
+ >>> import narwhals as nw
+ >>> from narwhals.typing import FrameT
+ >>> @nw.narwhalify
+ ... def agnostic_func(df: FrameT) -> FrameT:
+ ... return df.with_columns(c=nw.col("a") + 1)
+"""
+
+DataFrameT = TypeVar("DataFrameT", bound="DataFrame[Any]")
+"""TypeVar bound to Narwhals DataFrame.
+
+Use this if your function can accept a Narwhals DataFrame and returns a Narwhals
+DataFrame backed by the same backend.
+
+Examples:
+ >>> import narwhals as nw
+ >>> from narwhals.typing import DataFrameT
+ >>> @nw.narwhalify
+ >>> def func(df: DataFrameT) -> DataFrameT:
+ ... return df.with_columns(c=df["a"] + 1)
+"""
+
+IntoSeriesT = TypeVar("IntoSeriesT", bound="IntoSeries")
+"""TypeVar bound to object convertible to Narwhals Series.
+
+Use this if your function accepts an object which can be converted to `nw.Series`
+and returns an object of the same class.
+
+Examples:
+ >>> import narwhals as nw
+ >>> from narwhals.typing import IntoSeriesT
+ >>> def agnostic_abs(s_native: IntoSeriesT) -> IntoSeriesT:
+ ... s = nw.from_native(s_native, series_only=True)
+ ... return s.abs().to_native()
+"""
+
+
+__all__ = [
+ "DataFrameT",
+ "Frame",
+ "FrameT",
+ "IntoDataFrame",
+ "IntoDataFrameT",
+ "IntoExpr",
+ "IntoFrame",
+ "IntoFrameT",
+ "IntoSeries",
+ "IntoSeriesT",
+]