class _MPMathFunction(SageFunction): attributes = ('Listable', 'NumericFunction') def eval(self, z): return None def apply_exact(self, z, evaluation): '%(name)s[z_?ExactNumberQ]' expr = Expression(self.get_name(), z).to_sympy() result = from_sympy(expr) # evaluate leaves to convert e.g. Plus[2, I] -> Complex[2, 1] result = result.evaluate_leaves(evaluation) return result def apply_inexact(self, z, evaluation): '%(name)s[z_Real|z_Complex?InexactNumberQ]' with workprec(z.get_precision()): z = gmpy2mpmath(z.value) try: result = self.eval(z) except ValueError, exc: text = str(exc) if text == 'gamma function pole': return Symbol('ComplexInfinity') else: raise except ZeroDivisionError: return try: result = mpmath2gmpy(result) except SpecialValueError, exc: return Symbol(exc.name)
def apply_N(self, prec, evaluation): 'N[E, prec_]' prec = get_precision(prec, evaluation) if prec is not None: with workprec(prec): return Real(mpmath2gmpy(mpmath.e))
def apply_inexact(self, n, k, evaluation): 'Binomial[n_?InexactNumberQ, k_?NumberQ]' with workprec(min_prec(n, k)): n = gmpy2mpmath(n.value) k = gmpy2mpmath(k.value) result = mpmath.binomial(n, k) try: result = mpmath2gmpy(result) except SpecialValueError, exc: return Symbol(exc.name) number = Number.from_mp(result) return number
def apply(self, n, b, evaluation): 'IntegerLength[n_, b_]' # Use interval arithmetic to account for "right" rounding n, b = n.get_int_value(), b.get_int_value() if n is None or b is None: evaluation.message('IntegerLength', 'int') return if b <= 1: evaluation.message('IntegerLength', 'base', b) return result = mp.mpf(iv.log(iv.mpf(mpz2mpmath(abs(n))), mpz2mpmath(b)).b) result = mpz(mpmath2gmpy(result)) + 1 return Integer(result)