def pyobject(self, ex, obj): from mathics.core import expression from mathics.core.expression import Number if obj is None: return expression.Symbol('Null') elif isinstance(obj, (list, tuple)) or is_Vector(obj): return expression.Expression('List', *(from_sage(item, self.subs) for item in obj)) elif isinstance(obj, Constant): return expression.Symbol(obj._conversions.get('mathematica', obj._name)) elif is_Integer(obj): return expression.Integer(str(obj)) elif isinstance(obj, sage.Rational): rational = expression.Rational(str(obj)) if rational.value.denom() == 1: return expression.Integer(rational.value.numer()) else: return rational elif isinstance(obj, sage.RealDoubleElement) or is_RealNumber(obj): return expression.Real(str(obj)) elif is_ComplexNumber(obj): real = Number.from_string(str(obj.real())).value imag = Number.from_string(str(obj.imag())).value return expression.Complex(real, imag) elif isinstance(obj, NumberFieldElement_quadratic): # TODO: this need not be a complex number, but we assume so! real = Number.from_string(str(obj.real())).value imag = Number.from_string(str(obj.imag())).value return expression.Complex(real, imag) else: return expression.from_python(obj)
def _make_Rational(self, x, y): return ma.Rational(x, y)
def convert_Number(self, node): s = node.value if s[0] == '-': sign_prefix, s = s[0], s[1:] sign = -1 else: sign_prefix = '' sign = 1 # fast exit if s.isdigit(): return ma.Integer(sign * int(s)) # Look for base s = s.split('^^') if len(s) == 1: base, s = 10, s[0] else: assert len(s) == 2 base, s = int(s[0]), s[1] assert 2 <= base <= 36 # Look for mantissa s = s.split('*^') if len(s) == 1: n, s = 0, s[0] else: # TODO: modify regex and provide error message if n not an int n, s = int(s[1]), s[0] # Look at precision ` suffix to get precision/accuracy prec, acc = None, None s = s.split('`', 1) if len(s) == 1: s, suffix = s[0], None else: s, suffix = s[0], s[1] # Look for decimal point if '.' not in s: if suffix is None: if n < 0: return ma.Rational(sign * int(s, base), base**abs(n)) else: return ma.Integer(sign * int(s, base) * (base**n)) else: s = s + '.' if base == 10: man = s if n != 0: s = s + 'E' + str(n) if suffix is None: # MachineReal/PrecisionReal is determined by number of digits # in the mantissa d = len(man) - 2 # one less for decimal point if d < reconstruct_digits(machine_precision): result = float(sign_prefix + s) else: result = sympy.Float(str(sign_prefix + s), d) elif suffix == '': result = float(sign_prefix + s) elif suffix.startswith('`'): acc = float(suffix[1:]) x = float(s) if x == 0: prec10 = acc else: prec10 = acc + log10(x) result = sympy.Float(str(sign_prefix + s), prec10) else: result = sympy.Float(str(sign_prefix + s), float(suffix)) if isinstance(result, float): return ma.MachineReal(result) elif isinstance(result, sympy.Float): return ma.PrecisionReal(result) # Put into standard form mantissa * base ^ n s = s.split('.') if len(s) == 1: man = s[0] else: n -= len(s[1]) man = s[0] + s[1] man = sign * int(man, base) if n >= 0: result = sympy.Integer(man * base**n) else: result = sympy.Rational(man, base**-n) x = float(result) # determine `prec10` the digits of precision in base 10 if suffix is None: acc = len(s[1]) acc10 = acc * log10(base) if x == 0: prec10 = acc10 else: prec10 = acc10 + log10(abs(x)) if prec10 < reconstruct_digits(machine_precision): prec10 = None elif suffix == '': prec10 = None elif suffix.startswith('`'): acc = float(suffix[1:]) acc10 = acc * log10(base) if x == 0: prec10 = acc10 else: prec10 = acc10 + log10(abs(x)) else: prec = float(suffix) prec10 = prec * log10(base) if prec10 is None: return ma.MachineReal(x) else: result = sympy.Float(result, prec10) return ma.PrecisionReal(result)
def convert_Number(self, node): s = node.value if s[0] == '-': sign_prefix, s = s[0], s[1:] sign = -1 else: sign_prefix = '' sign = 1 # fast exit if s.isdigit(): return ma.Integer(sign * int(s)) # Look for base s = s.split('^^') if len(s) == 1: base, s = 10, s[0] else: assert len(s) == 2 base, s = int(s[0]), s[1] assert 2 <= base <= 36 # Look for mantissa s = s.split('*^') if len(s) == 1: n, s = 0, s[0] else: # TODO: modify regex and provide error message if n not an int n, s = int(s[1]), s[0] # Look at precision ` suffix to get precision/accuracy prec, acc = None, None s = s.split('`', 1) if len(s) == 1: suffix, s = None, s[0] else: suffix, s = s[1], s[0] if suffix == '': prec = machine_precision elif suffix.startswith('`'): acc = float(suffix[1:]) else: if re.match('0+$', s) is not None: return ma.Integer(0) prec = float(suffix) # Look for decimal point if s.count('.') == 0: if suffix is None: if n < 0: return ma.Rational(sign * int(s, base), base**abs(n)) else: return ma.Integer(sign * int(s, base) * (base**n)) else: s = s + '.' if base == 10: if n != 0: s = s + 'E' + str(n) # sympy handles this if acc is not None: if float(s) == 0: prec = 0. else: prec = acc + log10(float(s)) + n # XXX if prec is not None: prec = dps(prec) # return ma.Real(s, prec, acc) return ma.Real(sign_prefix + s, prec) else: # Convert the base assert isinstance(base, int) and 2 <= base <= 36 # Put into standard form mantissa * base ^ n s = s.split('.') if len(s) == 1: man = s[0] else: n -= len(s[1]) man = s[0] + s[1] man = sign * int(man, base) if n >= 0: result = ma.Integer(man * base**n) else: result = ma.Rational(man, base**-n) if acc is None and prec is None: acc = len(s[1]) acc10 = acc * log10(base) prec10 = acc10 + log10(result.to_python()) if prec10 < 18: prec10 = None elif acc is not None: acc10 = acc * log10(base) prec10 = acc10 + log10(result.to_python()) elif prec is not None: if prec == machine_precision: prec10 = machine_precision else: prec10 = prec * log10(base) # XXX if prec10 is None: prec10 = machine_precision else: prec10 = dps(prec10) return result.round(prec10)