def apply(self, z, evaluation): '%(name)s[z__]' args = z.numerify(evaluation).get_sequence() mpmath_function = self.get_mpmath_function(args) result = None # 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] return result.evaluate_leaves(evaluation) elif mpmath_function is None: return if not all(isinstance(arg, Number) for arg in args): return if any(arg.is_machine_precision() for arg in args): # if any argument has machine precision then the entire calculation # is done with machine precision. float_args = [ arg.round().get_float_value(permit_complex=True) for arg in args ] if None in float_args: return result = self.call_mpmath(mpmath_function, float_args) if isinstance(result, (mpmath.mpc, mpmath.mpf)): if mpmath.isinf(result) and isinstance(result, mpmath.mpc): result = Symbol('ComplexInfinity') elif mpmath.isinf(result) and result > 0: result = Expression('DirectedInfinity', Integer(1)) elif mpmath.isinf(result) and result < 0: result = Expression('DirectedInfinity', Integer(-1)) elif mpmath.isnan(result): result = Symbol('Indeterminate') else: result = Number.from_mpmath(result) else: prec = min_prec(*args) d = dps(prec) args = [ Expression('N', arg, Integer(d)).evaluate(evaluation) for arg in args ] with mpmath.workprec(prec): mpmath_args = [x.to_mpmath() for x in args] if None in mpmath_args: return result = self.call_mpmath(mpmath_function, mpmath_args) if isinstance(result, (mpmath.mpc, mpmath.mpf)): result = Number.from_mpmath(result, d) return result
def apply(self, z, evaluation): '%(name)s[z__]' args = z.numerify(evaluation).get_sequence() mpmath_function = self.get_mpmath_function(args) result = None # 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] return result.evaluate_leaves(evaluation) elif mpmath_function is None: return if not all(isinstance(arg, Number) for arg in args): return if any(arg.is_machine_precision() for arg in args): # if any argument has machine precision then the entire calculation # is done with machine precision. float_args = [arg.round().get_float_value(permit_complex=True) for arg in args] if None in float_args: return result = self.call_mpmath(mpmath_function, float_args) if isinstance(result, (mpmath.mpc, mpmath.mpf)): if mpmath.isinf(result) and isinstance(result, mpmath.mpc): result = Symbol('ComplexInfinity') elif mpmath.isinf(result) and result > 0: result = Expression('DirectedInfinity', Integer(1)) elif mpmath.isinf(result) and result < 0: result = Expression('DirectedInfinity', Integer(-1)) elif mpmath.isnan(result): result = Symbol('Indeterminate') else: result = Number.from_mpmath(result) else: prec = min_prec(*args) d = dps(prec) args = [Expression('N', arg, Integer(d)).evaluate(evaluation) for arg in args] with mpmath.workprec(prec): mpmath_args = [x.to_mpmath() for x in args] if None in mpmath_args: return result = self.call_mpmath(mpmath_function, mpmath_args) if isinstance(result, (mpmath.mpc, mpmath.mpf)): result = Number.from_mpmath(result, d) return result
def apply(self, z, s, a, evaluation): '%(name)s[z_, s_, a_]' py_z = z.to_python() py_s = s.to_python() py_a = a.to_python() try: return Number.from_mpmath(mpmath.lerchphi(py_z, py_s, py_a)) except: pass
def mp_eig(mp_matrix) -> Expression: try: _, ER = mp.eig(mp_matrix) except: return None eigenvalues = ER.tolist() # Sort the eigenvalues in the Mathematica convention: largest first. eigenvalues.sort(key=lambda v: (abs(v[0]), -v[0].real, -(v[0].imag)), reverse=True) eigenvalues = [[Number.from_mpmath(c) for c in row] for row in eigenvalues] return Expression("List", *eigenvalues)
def apply_N(self, k, precision, evaluation): 'N[AiryBiZero[k_Integer], precision_]' try: d = get_precision(precision, evaluation) except PrecisionValueError: return if d is None: p = machine_precision else: p = _prec(d) k_int = k.get_int_value() with mpmath.workprec(p): result = mpmath.airybizero(k_int) return Number.from_mpmath(result, d)
def apply(self, items, evaluation): 'Times[items___]' items = items.numerify(evaluation).get_sequence() leaves = [] numbers = [] prec = min_prec(*items) is_machine_precision = any(item.is_machine_precision() for item in items) # find numbers and simplify Times -> Power for item in items: if isinstance(item, Number): numbers.append(item) elif leaves and item == leaves[-1]: leaves[-1] = Expression('Power', leaves[-1], Integer(2)) elif (leaves and item.has_form('Power', 2) and leaves[-1].has_form('Power', 2) and item.leaves[0].same(leaves[-1].leaves[0])): leaves[-1].leaves[1] = Expression( 'Plus', item.leaves[1], leaves[-1].leaves[1]) elif (leaves and item.has_form('Power', 2) and item.leaves[0].same(leaves[-1])): leaves[-1] = Expression( 'Power', leaves[-1], Expression('Plus', item.leaves[1], Integer(1))) elif (leaves and leaves[-1].has_form('Power', 2) and leaves[-1].leaves[0].same(item)): leaves[-1] = Expression('Power', item, Expression( 'Plus', Integer(1), leaves[-1].leaves[1])) else: leaves.append(item) if numbers: if prec is not None: if is_machine_precision: numbers = [item.to_mpmath() for item in numbers] number = mpmath.fprod(numbers) number = Number.from_mpmath(number) else: with mpmath.workprec(prec): numbers = [item.to_mpmath() for item in numbers] number = mpmath.fprod(numbers) number = Number.from_mpmath(number, dps(prec)) else: number = sympy.Mul(*[item.to_sympy() for item in numbers]) number = from_sympy(number) else: number = Integer(1) if number.same(Integer(1)): number = None elif number.is_zero: return number elif number.same(Integer(-1)) and leaves and leaves[0].has_form('Plus', None): leaves[0].leaves = [Expression('Times', Integer(-1), leaf) for leaf in leaves[0].leaves] number = None for leaf in leaves: leaf.last_evaluated = None if number is not None: leaves.insert(0, number) if not leaves: return Integer(1) elif len(leaves) == 1: return leaves[0] else: return Expression('Times', *leaves)
def apply(self, items, evaluation): 'Plus[items___]' items = items.numerify(evaluation).get_sequence() leaves = [] last_item = last_count = None prec = min_prec(*items) is_machine_precision = any(item.is_machine_precision() for item in items) numbers = [] def append_last(): if last_item is not None: if last_count == 1: leaves.append(last_item) else: if last_item.has_form('Times', None): last_item.leaves.insert(0, from_sympy(last_count)) leaves.append(last_item) else: leaves.append(Expression( 'Times', from_sympy(last_count), last_item)) for item in items: if isinstance(item, Number): numbers.append(item) else: count = rest = None if item.has_form('Times', None): for leaf in item.leaves: if isinstance(leaf, Number): count = leaf.to_sympy() rest = item.leaves[:] rest.remove(leaf) if len(rest) == 1: rest = rest[0] else: rest.sort() rest = Expression('Times', *rest) break if count is None: count = sympy.Integer(1) rest = item if last_item is not None and last_item == rest: last_count = last_count + count else: append_last() last_item = rest last_count = count append_last() if numbers: if prec is not None: if is_machine_precision: numbers = [item.to_mpmath() for item in numbers] number = mpmath.fsum(numbers) number = Number.from_mpmath(number) else: with mpmath.workprec(prec): numbers = [item.to_mpmath() for item in numbers] number = mpmath.fsum(numbers) number = Number.from_mpmath(number, dps(prec)) else: number = from_sympy(sum(item.to_sympy() for item in numbers)) else: number = Integer(0) if not number.same(Integer(0)): leaves.insert(0, number) if not leaves: return Integer(0) elif len(leaves) == 1: return leaves[0] else: leaves.sort() return Expression('Plus', *leaves)