def get_constant(self, precision, evaluation, preference=None): ## print("XXX", self, preference) if preference is None: preference = ( evaluation.parse("Settings`$PreferredBackendMethod") .evaluate(evaluation) .get_string_value() ) # TODO: validate PreferredBackendMethod is in "mpmath", "numpy", "sympy" try: d = get_precision(precision, evaluation) except PrecisionValueError: d = None conversion_fn = MachineReal if d is None else PrecisionReal # print("XXX1", self, preference, conversion_fn) if preference == "sympy" and hasattr(self, "sympy_name"): value = sympy_constant(self.sympy_name, d) elif preference == "mpmath" and hasattr(self, "mpmath_name"): value = mp_constant(self.mpmath_name, d) elif preference == "numpy" and hasattr(self, "numpy_name"): value = numpy_constant(self.numpy_name) elif hasattr(self, "mpmath_name"): value = mp_constant(self.mpmath_name, d) elif hasattr(self, "sympy_name"): value = sympy_constant(self.sympy_name, d) elif hasattr(self, "numpy_name"): value = numpy_constant(self.numpy_name) return conversion_fn(value)
def apply_other(self, expr, prec, evaluation): "N[expr_, prec_]" try: d = get_precision(prec, evaluation) except PrecisionValueError: return if expr.get_head_name() in ("System`List", "System`Rule"): return Expression( expr.head, *[self.apply_other(leaf, prec, evaluation) for leaf in expr.leaves] ) # Special case for the Root builtin if expr.has_form("Root", 2): return from_sympy(sympy.N(expr.to_sympy(), d)) if isinstance(expr, Number): return expr.round(d) name = expr.get_lookup_name() if name != "": nexpr = Expression("N", expr, prec) result = evaluation.definitions.get_value( name, "System`NValues", nexpr, evaluation ) if result is not None: if not result.same(nexpr): result = Expression("N", result, prec).evaluate(evaluation) return result if expr.is_atom(): return expr else: attributes = expr.head.get_attributes(evaluation.definitions) if "System`NHoldAll" in attributes: eval_range = () elif "System`NHoldFirst" in attributes: eval_range = range(1, len(expr.leaves)) elif "System`NHoldRest" in attributes: if len(expr.leaves) > 0: eval_range = (0,) else: eval_range = () else: eval_range = range(len(expr.leaves)) head = Expression('N', expr.head, prec).evaluate(evaluation) leaves = expr.get_mutable_leaves() for index in eval_range: leaves[index] = Expression("N", leaves[index], prec).evaluate( evaluation ) return Expression(head, *leaves)
def apply_N(self, precision, evaluation): 'N[E, precision_]' try: d = get_precision(precision, evaluation) except PrecisionValueError: return if d is None: return MachineReal(math.e) else: return PrecisionReal(sympy.E.n(d))
def get_constant(self, precision, evaluation, have_mpmath=False): try: d = get_precision(precision, evaluation) except PrecisionValueError: return sympy_fn = self.to_sympy() if d is None: result = self.get_mpmath_function() if have_mpmath else sympy_fn() return MachineReal(result) else: return PrecisionReal(sympy_fn.n(d))
def apply_N(self, precision, evaluation, options={}): "N[Degree, precision_, OptionsPattern[%(name)s]]" try: if precision: d = get_precision(precision, evaluation) else: d = get_precision(Symbol("System`MachinePrecision"), evaluation) except PrecisionValueError: return # FIXME: There are all sorts of interactions between in the trig functions, # that are expected to work out right. Until we have convertion between # mpmath and sympy worked out so that values can be made the to the same # precision and compared. we have to not use mpmath right now. # return self.get_constant(precision, evaluation, preference="mpmath") if d is None: return MachineReal(math.pi / 180) else: return PrecisionReal((sympy.pi / 180).n(d))
def apply_N(self, precision, evaluation): "N[Pi, precision_]" try: d = get_precision(precision, evaluation) except PrecisionValueError: return if d is None: return MachineReal(math.pi) else: return PrecisionReal(sympy.pi.n(d))
def apply_N(self, precision, evaluation): "N[Catalan, precision_]" try: d = get_precision(precision, evaluation) except PrecisionValueError: return if d is None: return MachineReal(mpmath.catalan) else: return PrecisionReal(sympy.Catalan.n(d))
def get_constant(self, precision, evaluation, preference=None): # first, determine the precision machine_d = int(0.30103 * machine_precision) d = None if precision: try: d = get_precision(precision, evaluation) except PrecisionValueError: pass if d is None: d = machine_d # If preference not especified, determine it # from the precision. if preference is None: if d <= machine_d: preference = "numpy" else: preference = "mpmath" # If preference is not valid, send a message and return. if not (preference in ("sympy", "numpy", "mpmath")): evaluation.message( f'{preference} not in ("sympy", "numpy", "mpmath")') return # Try to determine the numeric value value = None if preference == "mpmath" and not hasattr(self, "mpmath_name"): preference = "numpy" elif preference == "sympy" and not hasattr(self, "sympy_name"): preference = "numpy" if preference == "numpy" and not hasattr(self, "numpy_name"): if hasattr(self, "sympy_name"): preference = "sympy" elif hasattr(self, "mpmath_name"): preference = "mpmath" else: preference = "" if preference == "numpy": value = numpy_constant(self.numpy_name) if d == machine_d: return MachineReal(value) if preference == "sympy": value = sympy_constant(self.sympy_name, d + 2) if preference == "mpmath": value = mp_constant(self.mpmath_name, d * 2) if value: return PrecisionReal(sympy.Float(str(value), d)) # If the value is not available, return none # and keep it unevaluated. return
def apply_other(self, expr, prec, evaluation): 'N[expr_, prec_]' try: d = get_precision(prec, evaluation) except PrecisionValueError: return if expr.get_head_name() in ('System`List', 'System`Rule'): return Expression( expr.head, *[ self.apply_other(leaf, prec, evaluation) for leaf in expr.leaves ]) if isinstance(expr, Number): return expr.round(d) name = expr.get_lookup_name() if name != '': nexpr = Expression('N', expr, prec) result = evaluation.definitions.get_value(name, 'System`NValues', nexpr, evaluation) if result is not None: if not result.same(nexpr): result = Expression('N', result, prec).evaluate(evaluation) return result if expr.is_atom(): return expr else: attributes = expr.head.get_attributes(evaluation.definitions) if 'System`NHoldAll' in attributes: eval_range = () elif 'System`NHoldFirst' in attributes: eval_range = range(1, len(expr.leaves)) elif 'System`NHoldRest' in attributes: if len(expr.leaves) > 0: eval_range = (0, ) else: eval_range = () else: eval_range = range(len(expr.leaves)) head = Expression('N', expr.head, prec).evaluate(evaluation) leaves = expr.leaves[:] for index in eval_range: leaves[index] = Expression('N', leaves[index], prec).evaluate(evaluation) return Expression(head, *leaves)
def apply_other(self, expr, prec, evaluation): 'N[expr_, prec_]' try: d = get_precision(prec, evaluation) except PrecisionValueError: return if expr.get_head_name() in ('System`List', 'System`Rule'): return Expression( expr.head, *[self.apply_other(leaf, prec, evaluation) for leaf in expr.leaves]) if isinstance(expr, Number): return expr.round(d) name = expr.get_lookup_name() if name != '': nexpr = Expression('N', expr, prec) result = evaluation.definitions.get_value( name, 'System`NValues', nexpr, evaluation) if result is not None: if not result.same(nexpr): result = Expression('N', result, prec).evaluate(evaluation) return result if expr.is_atom(): return expr else: attributes = expr.head.get_attributes(evaluation.definitions) if 'System`NHoldAll' in attributes: eval_range = () elif 'System`NHoldFirst' in attributes: eval_range = range(1, len(expr.leaves)) elif 'System`NHoldRest' in attributes: if len(expr.leaves) > 0: eval_range = (0,) else: eval_range = () else: eval_range = range(len(expr.leaves)) head = Expression('N', expr.head, prec).evaluate(evaluation) leaves = expr.leaves[:] for index in eval_range: leaves[index] = Expression( 'N', leaves[index], prec).evaluate(evaluation) return Expression(head, *leaves)
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_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 from_mpmath(result, d)
def get_constant(self, precision, evaluation, preference="mpmath"): try: d = get_precision(precision, evaluation) except PrecisionValueError: return mpmath_name = self.mpmath_name if d is None: return MachineReal(mp_fn(mpmath_name)) elif preference == "mpmath": result = mp_fn(mpmath_name, d) else: sympy_fn = self.to_sympy() try: result = sympy_fn.n(d) except: from trepan.api import debug; debug() pass return PrecisionReal(result)
def get_constant(self, precision, evaluation, preference="sympy"): try: d = get_precision(precision, evaluation) except PrecisionValueError: return sympy_fn = self.to_sympy() if d is None: if hasattr(self, "mpmath_name"): # Prefer mpmath when precision is not given. result = mp_fn(self.mpmath_name) else: result = sympy_fn() return MachineReal(result) if preference == "sympy": result = sympy_fn_n(d) elif hasattr(self, "mpmath_name"): result = mp_fn(self.mpmath_name, d) return PrecisionReal(result)