def apply(self, z, evaluation): "%(name)s[z__]" args = z.get_sequence() if len(args) != self.nargs: return # if no arguments are inexact attempt to use sympy if len([True for x in args if Expression("InexactNumberQ", x).evaluate(evaluation).is_true()]) == 0: expr = Expression(self.get_name(), *args).to_sympy() result = from_sympy(expr) # evaluate leaves to convert e.g. Plus[2, I] -> Complex[2, 1] result = result.evaluate_leaves(evaluation) else: prec = min_prec(*args) with mpmath.workprec(prec): mpmath_args = [sympy2mpmath(x.to_sympy()) for x in args] if None in mpmath_args: return try: result = self.eval(*mpmath_args) result = from_sympy(mpmath2sympy(result, prec)) except ValueError, exc: text = str(exc) if text == "gamma function pole": return Symbol("ComplexInfinity") else: raise except ZeroDivisionError: return except SpecialValueError, exc: return Symbol(exc.name)
def apply(self, z, evaluation): '%(name)s[z__]' args = z.get_sequence() if len(args) != self.nargs: return # if no arguments are inexact attempt to use sympy if all(not x.is_inexact() for x in args): result = Expression(self.get_name(), *args).to_sympy() result = self.prepare_mathics(result) result = from_sympy(result) # evaluate leaves to convert e.g. Plus[2, I] -> Complex[2, 1] result = result.evaluate_leaves(evaluation) else: prec = min_prec(*args) with mpmath.workprec(prec): mpmath_args = [sympy2mpmath(x.to_sympy()) for x in args] if None in mpmath_args: return try: result = self.eval(*mpmath_args) result = from_sympy(mpmath2sympy(result, prec)) except ValueError, exc: text = str(exc) if text == 'gamma function pole': return Symbol('ComplexInfinity') else: raise except ZeroDivisionError: return except SpecialValueError, exc: return Symbol(exc.name)
def apply_inexact(self, z, evaluation): '%(name)s[z_Real|z_Complex?InexactNumberQ]' prec = z.get_precision() with mpmath.workprec(prec): z = sympy2mpmath(z.to_sympy()) if z is None: return try: result = self.eval(z) result = mpmath2sympy(result, prec) except ValueError, exc: text = str(exc) if text == 'gamma function pole': return Symbol('ComplexInfinity') else: raise except ZeroDivisionError: return
def apply(self, items, evaluation): 'Power[items__]' items_sequence = items.get_sequence() if len(items_sequence) == 2: x, y = items_sequence else: return Expression('Power', *items_sequence) if y.get_int_value() == 1: return x elif x.get_int_value() == 1: return x elif y.get_int_value() == 0: if x.get_int_value() == 0: evaluation.message('Power', 'indet', Expression('Power', x, y)) return Symbol('Indeterminate') else: return Integer(1) elif x.has_form('Power', 2) and isinstance(y, Integer): return Expression('Power', x.leaves[0], Expression('Times', x.leaves[1], y)) elif x.has_form('Times', None) and isinstance(y, Integer): return Expression( 'Times', *[Expression('Power', leaf, y) for leaf in x.leaves]) elif (isinstance(x, Number) and isinstance(y, Number) and not (x.is_inexact() or y.is_inexact())): sym_x, sym_y = x.to_sympy(), y.to_sympy() try: if sympy.re(sym_y) >= 0: result = sym_x**sym_y else: if sym_x == 0: evaluation.message('Power', 'infy') return Symbol('ComplexInfinity') result = sympy.Integer(1) / (sym_x**(-sym_y)) if isinstance(result, sympy.Pow): result = result.simplify() args = [from_sympy(expr) for expr in result.as_base_exp()] result = Expression('Power', *args) result = result.evaluate_leaves(evaluation) return result return from_sympy(result) except ValueError: return Expression('Power', x, y) except ZeroDivisionError: evaluation.message('Power', 'infy') return Symbol('ComplexInfinity') elif (isinstance(x, Number) and isinstance(y, Number) and (x.is_inexact() or y.is_inexact())): try: prec = min_prec(x, y) with mpmath.workprec(prec): mp_x = sympy2mpmath(x.to_sympy()) mp_y = sympy2mpmath(y.to_sympy()) result = mp_x**mp_y if isinstance(result, mpmath.mpf): return Real(str(result), prec) elif isinstance(result, mpmath.mpc): return Complex(str(result.real), str(result.imag), prec) except ZeroDivisionError: evaluation.message('Power', 'infy') return Symbol('ComplexInfinity') else: numerified_items = items.numerify(evaluation) return Expression('Power', *numerified_items.get_sequence())
def apply(self, items, evaluation): "Power[items__]" items_sequence = items.get_sequence() if len(items_sequence) == 2: x, y = items_sequence else: return Expression("Power", *items_sequence) if y.get_int_value() == 1: return x elif x.get_int_value() == 1: return x elif y.get_int_value() == 0: if x.get_int_value() == 0: evaluation.message("Power", "indet", Expression("Power", x, y)) return Symbol("Indeterminate") else: return Integer(1) elif x.has_form("Power", 2) and isinstance(y, Integer): return Expression("Power", x.leaves[0], Expression("Times", x.leaves[1], y)) elif x.has_form("Times", None) and isinstance(y, Integer): return Expression("Times", *[Expression("Power", leaf, y) for leaf in x.leaves]) elif isinstance(x, Number) and isinstance(y, Number) and not (x.is_inexact() or y.is_inexact()): sym_x, sym_y = x.to_sympy(), y.to_sympy() try: if sym_y >= 0: result = sym_x ** sym_y else: if sym_x == 0: evaluation.message("Power", "infy") return Symbol("ComplexInfinity") result = sympy.Integer(1) / (sym_x ** (-sym_y)) if isinstance(result, sympy.Pow): result = result.simplify() args = [from_sympy(expr) for expr in result.as_base_exp()] result = Expression("Power", *args) result = result.evaluate_leaves(evaluation) return result return from_sympy(result) except ValueError: return Expression("Power", x, y) except ZeroDivisionError: evaluation.message("Power", "infy") return Symbol("ComplexInfinity") elif isinstance(x, Number) and isinstance(y, Number) and (x.is_inexact() or y.is_inexact()): try: prec = min(max(x.get_precision(), 64), max(y.get_precision(), 64)) with mpmath.workprec(prec): mp_x = sympy2mpmath(x.to_sympy()) mp_y = sympy2mpmath(y.to_sympy()) result = mp_x ** mp_y if isinstance(result, mpmath.mpf): return Real(str(result), prec) elif isinstance(result, mpmath.mpc): return Complex(str(result.real), str(result.imag), prec) except ZeroDivisionError: evaluation.message("Power", "infy") return Symbol("ComplexInfinity") else: numerified_items = items.numerify(evaluation) return Expression("Power", *numerified_items.get_sequence())