def apply_list(self, zmin, zmax, ns, evaluation): 'RandomComplex[{zmin_, zmax_}, ns_]' expr = Expression('RandomComplex', Expression('List', zmin, zmax), ns) if Expression('RealNumberQ', zmin).evaluate(evaluation): zmin = Complex(zmin, 0.0) if Expression('RealNumberQ', zmax).evaluate(evaluation): zmax = Complex(zmax, 0.0) if not (isinstance(zmin, Complex) and isinstance(zmax, Complex)): return evaluation.message('RandomComplex', 'unifr', Expression('List', zmin, zmax)) min_value, max_value = zmin.to_python(), zmax.to_python() py_ns = ns.to_python() if not isinstance(py_ns, list): py_ns = [py_ns] if not all([isinstance(i, int) and i >= 0 for i in py_ns]): return evaluation.message('RandomComplex', 'array', ns, expr) with RandomEnv(evaluation) as rand: def search_product(i): if i == len(py_ns) - 1: return Expression('List', *[ Complex( rand.randreal(min_value.real, max_value.real), rand.randreal(min_value.imag, max_value.imag) ) for j in range(py_ns[i])]) else: return Expression('List', *[ search_product(i + 1) for j in range(py_ns[i])]) return search_product(0)
def apply(self, zmin, zmax, evaluation): "RandomComplex[{zmin_, zmax_}]" if Expression("RealNumberQ", zmin).evaluate(evaluation): zmin = Complex(zmin, 0.0) if Expression("RealNumberQ", zmax).evaluate(evaluation): zmax = Complex(zmax, 0.0) if not (isinstance(zmin, Complex) and isinstance(zmax, Complex)): return evaluation.message("RandomComplex", "unifr", Expression("List", zmin, zmax)) min_value, max_value = zmin.to_python(), zmax.to_python() with RandomEnv(evaluation) as rand: return Complex(rand.randreal(min_value.real, max_value.real), rand.randreal(min_value.imag, max_value.imag))
def apply(self, zmin, zmax, evaluation): 'RandomComplex[{zmin_, zmax_}]' if Expression('RealNumberQ', zmin).evaluate(evaluation): zmin = Complex(zmin, 0.0) if Expression('RealNumberQ', zmax).evaluate(evaluation): zmax = Complex(zmax, 0.0) if not (isinstance(zmin, Complex) and isinstance(zmax, Complex)): return evaluation.message('RandomComplex', 'unifr', Expression('List', zmin, zmax)) min_value, max_value = zmin.to_python(), zmax.to_python() with RandomEnv(evaluation) as rand: return Complex(rand.randreal(min_value.real, max_value.real), rand.randreal(min_value.imag, max_value.imag))
def chop(expr, delta=10.0**(-10.0)): if isinstance(expr, Real): if -delta < expr.to_python() < delta: return Integer(0) #return expr elif isinstance(expr, Complex) and expr.get_precision() is not None: real, imag = expr.real, expr.imag if -delta < real.to_python() < delta: real = sympy.Integer(0) if -delta < imag.to_python() < delta: imag = sympy.Integer(0) if imag != 0: return Complex(real, imag) else: return Number.from_mp(real) elif isinstance(expr, Expression): return Expression(chop(expr.head), *[chop(leaf) for leaf in expr.leaves]) return expr
def apply_list(self, zmin, zmax, ns, evaluation): 'RandomComplex[{zmin_, zmax_}, ns_]' expr = Expression('RandomComplex', Expression('List', zmin, zmax), ns) min_value, max_value = self.to_complex(zmin, evaluation), self.to_complex(zmax, evaluation) if min_value is None or max_value is None: return evaluation.message('RandomComplex', 'unifr', Expression('List', zmin, zmax)) py_ns = ns.to_python() if not isinstance(py_ns, list): py_ns = [py_ns] if not all([isinstance(i, six.integer_types) and i >= 0 for i in py_ns]): return evaluation.message('RandomComplex', 'array', ns, expr) with RandomEnv(evaluation) as rand: real = rand.randreal(min_value.real, max_value.real, py_ns) imag = rand.randreal(min_value.imag, max_value.imag, py_ns) return instantiate_elements( stack_along_inner_axis([real, imag]), lambda c: Complex(Real(c[0]), Real(c[1])), d=2)
def apply_list(self, zmin, zmax, ns, evaluation): 'RandomComplex[{zmin_, zmax_}, ns_]' expr = Expression('RandomComplex', Expression('List', zmin, zmax), ns) if Expression('RealNumberQ', zmin).evaluate(evaluation): zmin = Complex(zmin, 0.0) if Expression('RealNumberQ', zmax).evaluate(evaluation): zmax = Complex(zmax, 0.0) if not (isinstance(zmin, Complex) and isinstance(zmax, Complex)): return evaluation.message('RandomComplex', 'unifr', Expression('List', zmin, zmax)) min_value, max_value = zmin.to_python(), zmax.to_python() py_ns = ns.to_python() if not isinstance(py_ns, list): py_ns = [py_ns] if not all([isinstance(i, int) and i >= 0 for i in py_ns]): return evaluation.message('RandomComplex', 'array', ns, expr) with RandomEnv(evaluation) as rand: def search_product(i): if i == len(py_ns) - 1: return Expression( 'List', *[ Complex( rand.randreal(min_value.real, max_value.real), rand.randreal(min_value.imag, max_value.imag)) for j in range(py_ns[i]) ]) else: return Expression( 'List', *[search_product(i + 1) for j in range(py_ns[i])]) return search_product(0)
def evaluate(self, evaluation): return Complex(Integer(0), Integer(1))
def from_sympy(expr): from mathics.builtin import sympy_to_mathics from mathics.core.expression import (Symbol, Integer, Rational, Real, Complex, String, Expression) from sympy.core import numbers, function, symbol if isinstance(expr, (tuple, list)): return Expression('List', *[from_sympy(item) for item in expr]) if isinstance(expr, int): return Integer(expr) if isinstance(expr, float): return Real(expr) if isinstance(expr, complex): return Complex(expr.real, expr.imag) if isinstance(expr, str): return String(expr) if expr is None: return Symbol('Null') if isinstance(expr, sympy.Matrix): return Expression( 'List', *[ Expression('List', *[from_sympy(item) for item in row]) for row in expr.tolist() ]) if expr.is_Atom: name = None if expr.is_Symbol: name = unicode(expr) if isinstance(expr, symbol.Dummy): name = name + ('__Dummy_%d' % expr.dummy_index) return Symbol(name, sympy_dummy=expr) if (( not name.startswith(sympy_symbol_prefix) or # noqa name.startswith(sympy_slot_prefix)) and name.startswith('C')): return Expression('C', int(name[1:])) if name.startswith(sympy_symbol_prefix): name = name[len(sympy_symbol_prefix):] if name.startswith(sympy_slot_prefix): index = name[len(sympy_slot_prefix):] return Expression('Slot', int(index)) elif expr.is_NumberSymbol: name = unicode(expr) if name is not None: builtin = sympy_to_mathics.get(name) if builtin is not None: name = builtin.get_name() return Symbol(name) elif isinstance(expr, (numbers.Infinity, numbers.ComplexInfinity)): return Symbol(expr.__class__.__name__) elif isinstance(expr, numbers.NegativeInfinity): return Expression('Times', Integer(-1), Symbol('Infinity')) elif isinstance(expr, numbers.ImaginaryUnit): return Complex(0, 1) elif isinstance(expr, numbers.Integer): return Integer(expr.p) elif isinstance(expr, numbers.Rational): if expr.q == 0: if expr.p > 0: return Symbol('Infinity') elif expr.p < 0: return Expression('Times', Integer(-1), Symbol('Infinity')) else: assert expr.p == 0 return Symbol('Indeterminate') return Rational(expr.p, expr.q) elif isinstance(expr, numbers.Float): return Real(expr) elif isinstance(expr, numbers.NaN): return Symbol('Indeterminate') elif isinstance(expr, function.FunctionClass): return Symbol(unicode(expr)) elif expr.is_number and all([x.is_Number for x in expr.as_real_imag()]): # Hack to convert 3 * I to Complex[0, 3] return Complex(*[from_sympy(arg) for arg in expr.as_real_imag()]) elif expr.is_Add: return Expression('Plus', *sorted([from_sympy(arg) for arg in expr.args])) elif expr.is_Mul: return Expression('Times', *sorted([from_sympy(arg) for arg in expr.args])) elif expr.is_Pow: return Expression('Power', *[from_sympy(arg) for arg in expr.args]) elif expr.is_Equality: return Expression('Equal', *[from_sympy(arg) for arg in expr.args]) elif isinstance(expr, SympyExpression): # print "SympyExpression: %s" % expr return expr.expr elif isinstance(expr, sympy.RootSum): return Expression('RootSum', from_sympy(expr.poly), from_sympy(expr.fun)) elif isinstance(expr, sympy.PurePoly): coeffs = expr.coeffs() monoms = expr.monoms() result = [] for coeff, monom in zip(coeffs, monoms): factors = [] if coeff != 1: factors.append(from_sympy(coeff)) for index, exp in enumerate(monom): if exp != 0: slot = Expression('Slot', index + 1) if exp == 1: factors.append(slot) else: factors.append( Expression('Power', slot, from_sympy(exp))) if factors: result.append(Expression('Times', *factors)) else: result.append(Integer(1)) return Expression('Function', Expression('Plus', *result)) elif isinstance(expr, sympy.Lambda): vars = [ sympy.Symbol('%s%d' % (sympy_slot_prefix, index + 1)) for index in range(len(expr.variables)) ] return Expression('Function', from_sympy(expr(*vars))) elif expr.is_Function or isinstance( expr, (sympy.Integral, sympy.Derivative, sympy.Sum, sympy.Product)): if isinstance(expr, sympy.Integral): name = 'Integral' elif isinstance(expr, sympy.Derivative): name = 'Derivative' else: name = expr.func.__name__ if name.startswith(sympy_symbol_prefix): name = name[len(sympy_symbol_prefix):] args = [from_sympy(arg) for arg in expr.args] builtin = sympy_to_mathics.get(name) if builtin is not None: name = builtin.get_name() args = builtin.from_sympy(args) return Expression(Symbol(name), *args) elif isinstance(expr, sympy.Tuple): return Expression('List', *[from_sympy(arg) for arg in expr.args]) # elif isinstance(expr, sympy.Sum): # return Expression('Sum', ) elif isinstance(expr, sympy.LessThan): return Expression('LessEqual', [from_sympy(arg) for arg in expr.args]) elif isinstance(expr, sympy.StrictLessThan): return Expression('Less', [from_sympy(arg) for arg in expr.args]) elif isinstance(expr, sympy.GreaterThan): return Expression('GreaterEqual', [from_sympy(arg) for arg in expr.args]) elif isinstance(expr, sympy.StrictGreaterThan): return Expression('Greater', [from_sympy(arg) for arg in expr.args]) elif isinstance(expr, sympy.Unequality): return Expression('Unequal', [from_sympy(arg) for arg in expr.args]) elif isinstance(expr, sympy.Equality): return Expression('Equal', [from_sympy(arg) for arg in expr.args]) else: raise ValueError("Unknown SymPy expression: %s" % expr)
def evaluate(self, evaluation): return Complex(Integer0, Integer1)
def apply(self, items, evaluation): 'Times[items___]' # TODO: Clean this up and optimise it items = items.numerify(evaluation).get_sequence() number = (sympy.Integer(1), sympy.Integer(0)) leaves = [] prec = min_prec(*items) is_real = all([not isinstance(i, Complex) for i in items]) for item in items: if isinstance(item, Number): if isinstance(item, Complex): sym_real, sym_imag = item.real.to_sympy( ), item.imag.to_sympy() else: sym_real, sym_imag = item.to_sympy(), sympy.Integer(0) if prec is not None: sym_real = sym_real.n(dps(prec)) sym_imag = sym_imag.n(dps(prec)) if sym_real.is_zero and sym_imag.is_zero and prec is None: return Integer('0') number = (number[0] * sym_real - number[1] * sym_imag, number[0] * sym_imag + number[1] * sym_real) 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 number == (1, 0): number = None elif number == (-1, 0) 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 if number is not None: if number[1].is_zero and is_real: leaves.insert(0, Number.from_mp(number[0], prec)) elif number[1].is_zero and number[1].is_Integer and prec is None: leaves.insert(0, Number.from_mp(number[0], prec)) else: leaves.insert( 0, Complex(from_sympy(number[0]), from_sympy(number[1]), prec)) if not leaves: return Integer(1) elif len(leaves) == 1: return leaves[0] else: return Expression('Times', *leaves)
def from_sympy(expr): from mathics.builtin import sympy_to_mathics from mathics.core.expression import (Symbol, Integer, Rational, Real, Complex, String, Expression, MachineReal) from mathics.core.numbers import machine_precision if isinstance(expr, (tuple, list)): return Expression('List', *[from_sympy(item) for item in expr]) if isinstance(expr, int): return Integer(expr) if isinstance(expr, float): return Real(expr) if isinstance(expr, complex): return Complex(Real(expr.real), Real(expr.imag)) if isinstance(expr, str): return String(expr) if expr is None: return Symbol('Null') if isinstance(expr, sympy.Matrix) or isinstance(expr, sympy.ImmutableMatrix): if len(expr.shape) == 2 and (expr.shape[1] == 1): # This is a vector (only one column) # Transpose and select first row to get result equivalent to Mathematica return Expression( 'List', *[from_sympy(item) for item in expr.T.tolist()[0]]) else: return Expression( 'List', *[[from_sympy(item) for item in row] for row in expr.tolist()]) if isinstance(expr, sympy.MatPow): return Expression('MatrixPower', from_sympy(expr.base), from_sympy(expr.exp)) if expr.is_Atom: name = None if expr.is_Symbol: name = str(expr) if isinstance(expr, sympy.Dummy): name = name + ('__Dummy_%d' % expr.dummy_index) return Symbol(name, sympy_dummy=expr) if is_Cn_expr(name): return Expression('C', int(name[1:])) if name.startswith(sympy_symbol_prefix): name = name[len(sympy_symbol_prefix):] if name.startswith(sympy_slot_prefix): index = name[len(sympy_slot_prefix):] return Expression('Slot', int(index)) elif expr.is_NumberSymbol: name = str(expr) if name is not None: builtin = sympy_to_mathics.get(name) if builtin is not None: name = builtin.get_name() return Symbol(name) elif isinstance( expr, (sympy.core.numbers.Infinity, sympy.core.numbers.ComplexInfinity)): return Symbol(expr.__class__.__name__) elif isinstance(expr, sympy.core.numbers.NegativeInfinity): return Expression('Times', Integer(-1), Symbol('Infinity')) elif isinstance(expr, sympy.core.numbers.ImaginaryUnit): return Complex(Integer(0), Integer(1)) elif isinstance(expr, sympy.Integer): return Integer(int(expr)) elif isinstance(expr, sympy.Rational): numerator, denominator = map(int, expr.as_numer_denom()) if denominator == 0: if numerator > 0: return Symbol('Infinity') elif numerator < 0: return Expression('Times', Integer(-1), Symbol('Infinity')) else: assert numerator == 0 return Symbol('Indeterminate') return Rational(numerator, denominator) elif isinstance(expr, sympy.Float): if expr._prec == machine_precision: return MachineReal(float(expr)) return Real(expr) elif isinstance(expr, sympy.core.numbers.NaN): return Symbol('Indeterminate') elif isinstance(expr, sympy.core.function.FunctionClass): return Symbol(str(expr)) elif expr is sympy.true: return Symbol('True') elif expr is sympy.false: return Symbol('False') elif expr.is_number and all([x.is_Number for x in expr.as_real_imag()]): # Hack to convert 3 * I to Complex[0, 3] return Complex(*[from_sympy(arg) for arg in expr.as_real_imag()]) elif expr.is_Add: return Expression('Plus', *sorted([from_sympy(arg) for arg in expr.args])) elif expr.is_Mul: return Expression('Times', *sorted([from_sympy(arg) for arg in expr.args])) elif expr.is_Pow: return Expression('Power', *[from_sympy(arg) for arg in expr.args]) elif expr.is_Equality: return Expression('Equal', *[from_sympy(arg) for arg in expr.args]) elif isinstance(expr, SympyExpression): return expr.expr elif isinstance(expr, sympy.Piecewise): args = expr.args return Expression( 'Piecewise', Expression( 'List', *[ Expression('List', from_sympy(case), from_sympy(cond)) for case, cond in args ])) elif isinstance(expr, SympyPrime): return Expression('Prime', from_sympy(expr.args[0])) elif isinstance(expr, sympy.RootSum): return Expression('RootSum', from_sympy(expr.poly), from_sympy(expr.fun)) elif isinstance(expr, sympy.PurePoly): coeffs = expr.coeffs() monoms = expr.monoms() result = [] for coeff, monom in zip(coeffs, monoms): factors = [] if coeff != 1: factors.append(from_sympy(coeff)) for index, exp in enumerate(monom): if exp != 0: slot = Expression('Slot', index + 1) if exp == 1: factors.append(slot) else: factors.append( Expression('Power', slot, from_sympy(exp))) if factors: result.append(Expression('Times', *factors)) else: result.append(Integer(1)) return Expression('Function', Expression('Plus', *result)) elif isinstance(expr, sympy.CRootOf): try: e, i = expr.args except ValueError: return Expression('Null') try: e = sympy.PurePoly(e) except: pass return Expression('Root', from_sympy(e), i + 1) elif isinstance(expr, sympy.Lambda): vars = [ sympy.Symbol('%s%d' % (sympy_slot_prefix, index + 1)) for index in range(len(expr.variables)) ] return Expression('Function', from_sympy(expr(*vars))) elif expr.is_Function or isinstance( expr, (sympy.Integral, sympy.Derivative, sympy.Sum, sympy.Product)): if isinstance(expr, sympy.Integral): name = 'Integral' elif isinstance(expr, sympy.Derivative): name = 'Derivative' margs = [] for arg in expr.args: # parse (x, 1) ==> just x for test_conversion # IMHO this should be removed in future versions if isinstance(arg, sympy.Tuple): if arg[1] == 1: margs.append(from_sympy(arg[0])) else: margs.append(from_sympy(arg)) else: margs.append(from_sympy(arg)) builtin = sympy_to_mathics.get(name) return builtin.from_sympy(name, margs) elif isinstance(expr, sympy.sign): name = 'Sign' else: name = expr.func.__name__ if is_Cn_expr(name): return Expression(Expression('C', int(name[1:])), *[from_sympy(arg) for arg in expr.args]) if name.startswith(sympy_symbol_prefix): name = name[len(sympy_symbol_prefix):] args = [from_sympy(arg) for arg in expr.args] builtin = sympy_to_mathics.get(name) if builtin is not None: return builtin.from_sympy(name, args) return Expression(Symbol(name), *args) elif isinstance(expr, sympy.Tuple): return Expression('List', *[from_sympy(arg) for arg in expr.args]) # elif isinstance(expr, sympy.Sum): # return Expression('Sum', ) elif isinstance(expr, sympy.LessThan): return Expression('LessEqual', *[from_sympy(arg) for arg in expr.args]) elif isinstance(expr, sympy.StrictLessThan): return Expression('Less', *[from_sympy(arg) for arg in expr.args]) elif isinstance(expr, sympy.GreaterThan): return Expression('GreaterEqual', *[from_sympy(arg) for arg in expr.args]) elif isinstance(expr, sympy.StrictGreaterThan): return Expression('Greater', *[from_sympy(arg) for arg in expr.args]) elif isinstance(expr, sympy.Unequality): return Expression('Unequal', *[from_sympy(arg) for arg in expr.args]) elif isinstance(expr, sympy.Equality): return Expression('Equal', *[from_sympy(arg) for arg in expr.args]) elif isinstance(expr, sympy.O): if expr.args[0].func == sympy.core.power.Pow: [var, power] = [from_sympy(arg) for arg in expr.args[0].args] o = Expression('O', var) return Expression('Power', o, power) else: return Expression('O', from_sympy(expr.args[0])) else: raise ValueError( "Unknown SymPy expression: {} (instance of {})".format( expr, str(expr.__class__)))
def testInstances(self): # duplicate instantiations of same content (like Integer 5) to test for potential instantiation randomness. _test_group(list(map(lambda f: (f(), f()), (lambda: Integer(5), lambda: Rational(5, 2), lambda: Real(5.12345678), lambda: Complex(5, 2), lambda: String('xy'), lambda: Symbol('xy')))))
def testComplex(self): _test_group(Complex(1.2, 1.2), Complex(0.7, 1.8), Complex(1.8, 0.7), Complex(-0.7, 1.8), Complex(0.7, 1.81))
def from_sympy(expr): from mathics.builtin import sympy_to_mathics from mathics.core.expression import (Symbol, Integer, Rational, Real, Complex, String, Expression, MachineReal) from mathics.core.numbers import machine_precision from sympy.core import numbers, function, symbol if isinstance(expr, (tuple, list)): return Expression('List', *[from_sympy(item) for item in expr]) if isinstance(expr, int): return Integer(expr) if isinstance(expr, float): return Real(expr) if isinstance(expr, complex): return Complex(Real(expr.real), Real(expr.imag)) if isinstance(expr, six.string_types): return String(expr) if expr is None: return Symbol('Null') if isinstance(expr, sympy.Matrix): if len(expr.shape) == 2 and (expr.shape[1] == 1): # This is a vector (only one column) # Transpose and select first row to get result equivalent to Mathematica return Expression( 'List', *[from_sympy(item) for item in expr.T.tolist()[0]]) else: return Expression( 'List', *[[from_sympy(item) for item in row] for row in expr.tolist()]) if expr.is_Atom: name = None if expr.is_Symbol: name = six.text_type(expr) if isinstance(expr, symbol.Dummy): name = name + ('__Dummy_%d' % expr.dummy_index) return Symbol(name, sympy_dummy=expr) if is_Cn_expr(name): return Expression('C', int(name[1:])) if name.startswith(sympy_symbol_prefix): name = name[len(sympy_symbol_prefix):] if name.startswith(sympy_slot_prefix): index = name[len(sympy_slot_prefix):] return Expression('Slot', int(index)) elif expr.is_NumberSymbol: name = six.text_type(expr) if name is not None: builtin = sympy_to_mathics.get(name) if builtin is not None: name = builtin.get_name() return Symbol(name) elif isinstance(expr, (numbers.Infinity, numbers.ComplexInfinity)): return Symbol(expr.__class__.__name__) elif isinstance(expr, numbers.NegativeInfinity): return Expression('Times', Integer(-1), Symbol('Infinity')) elif isinstance(expr, numbers.ImaginaryUnit): return Complex(Integer(0), Integer(1)) elif isinstance(expr, numbers.Integer): return Integer(expr.p) elif isinstance(expr, numbers.Rational): if expr.q == 0: if expr.p > 0: return Symbol('Infinity') elif expr.p < 0: return Expression('Times', Integer(-1), Symbol('Infinity')) else: assert expr.p == 0 return Symbol('Indeterminate') return Rational(expr.p, expr.q) elif isinstance(expr, numbers.Float): if expr._prec == machine_precision: return MachineReal(float(expr)) return Real(expr) elif isinstance(expr, numbers.NaN): return Symbol('Indeterminate') elif isinstance(expr, function.FunctionClass): return Symbol(six.text_type(expr)) elif expr.is_number and all([x.is_Number for x in expr.as_real_imag()]): # Hack to convert 3 * I to Complex[0, 3] return Complex(*[from_sympy(arg) for arg in expr.as_real_imag()]) elif expr.is_Add: return Expression('Plus', *sorted([from_sympy(arg) for arg in expr.args])) elif expr.is_Mul: return Expression('Times', *sorted([from_sympy(arg) for arg in expr.args])) elif expr.is_Pow: return Expression('Power', *[from_sympy(arg) for arg in expr.args]) elif expr.is_Equality: return Expression('Equal', *[from_sympy(arg) for arg in expr.args]) elif isinstance(expr, SympyExpression): return expr.expr elif isinstance(expr, sympy.Piecewise): args = expr.args default = [] if len(args) > 0: default_case, default_cond = args[-1] if default_cond == sympy.true: args = args[:-1] if isinstance(default_case, sympy.Integer) and int(default_case) == 0: pass # ignore, as 0 default case is always implicit in Piecewise[] else: default = [from_sympy(default_case)] return Expression( 'Piecewise', Expression( 'List', *[ Expression('List', from_sympy(case), from_sympy(cond)) for case, cond in args ]), *default) elif isinstance(expr, sympy.RootSum): return Expression('RootSum', from_sympy(expr.poly), from_sympy(expr.fun)) elif isinstance(expr, sympy.PurePoly): coeffs = expr.coeffs() monoms = expr.monoms() result = [] for coeff, monom in zip(coeffs, monoms): factors = [] if coeff != 1: factors.append(from_sympy(coeff)) for index, exp in enumerate(monom): if exp != 0: slot = Expression('Slot', index + 1) if exp == 1: factors.append(slot) else: factors.append( Expression('Power', slot, from_sympy(exp))) if factors: result.append(Expression('Times', *factors)) else: result.append(Integer(1)) return Expression('Function', Expression('Plus', *result)) elif isinstance(expr, sympy.Lambda): vars = [ sympy.Symbol('%s%d' % (sympy_slot_prefix, index + 1)) for index in range(len(expr.variables)) ] return Expression('Function', from_sympy(expr(*vars))) elif expr.is_Function or isinstance( expr, (sympy.Integral, sympy.Derivative, sympy.Sum, sympy.Product)): if isinstance(expr, sympy.Integral): name = 'Integral' elif isinstance(expr, sympy.Derivative): name = 'Derivative' else: name = expr.func.__name__ if is_Cn_expr(name): return Expression(Expression('C', int(name[1:])), *[from_sympy(arg) for arg in expr.args]) if name.startswith(sympy_symbol_prefix): name = name[len(sympy_symbol_prefix):] args = [from_sympy(arg) for arg in expr.args] builtin = sympy_to_mathics.get(name) if builtin is not None: return builtin.from_sympy(name, args) return Expression(Symbol(name), *args) elif isinstance(expr, sympy.Tuple): return Expression('List', *[from_sympy(arg) for arg in expr.args]) # elif isinstance(expr, sympy.Sum): # return Expression('Sum', ) elif isinstance(expr, sympy.LessThan): return Expression('LessEqual', *[from_sympy(arg) for arg in expr.args]) elif isinstance(expr, sympy.StrictLessThan): return Expression('Less', *[from_sympy(arg) for arg in expr.args]) elif isinstance(expr, sympy.GreaterThan): return Expression('GreaterEqual', *[from_sympy(arg) for arg in expr.args]) elif isinstance(expr, sympy.StrictGreaterThan): return Expression('Greater', *[from_sympy(arg) for arg in expr.args]) elif isinstance(expr, sympy.Unequality): return Expression('Unequal', *[from_sympy(arg) for arg in expr.args]) elif isinstance(expr, sympy.Equality): return Expression('Equal', *[from_sympy(arg) for arg in expr.args]) elif expr is sympy.true: return Symbol('True') elif expr is sympy.false: return Symbol('False') else: raise ValueError("Unknown SymPy expression: %s" % expr)
def evaluate(self, evaluation): return Complex(mpz(0), mpz(1))
def evaluate(self, evaluation): return Complex(sympy.Integer(0), sympy.Integer(1))
def apply(self, items, evaluation): 'Plus[items___]' items = items.numerify(evaluation).get_sequence() leaves = [] last_item = last_count = None prec = min_prec(*items) is_real = all([not isinstance(i, Complex) for i in items]) if prec is None: number = (sympy.Integer(0), sympy.Integer(0)) else: number = (sympy.Float('0.0', dps(prec)), sympy.Float('0.0', dps(prec))) 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, Number.from_mp(last_count)) leaves.append(last_item) else: leaves.append( Expression('Times', Number.from_mp(last_count), last_item)) for item in items: if isinstance(item, Number): # TODO: Optimise this for the case of adding many real numbers if isinstance(item, Complex): sym_real, sym_imag = item.real.to_sympy( ), item.imag.to_sympy() else: sym_real, sym_imag = item.to_sympy(), sympy.Integer(0) if prec is not None: sym_real = sym_real.n(dps(prec)) sym_imag = sym_imag.n(dps(prec)) number = (number[0] + sym_real, number[1] + sym_imag) 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 = add(last_count, count) else: append_last() last_item = rest last_count = count append_last() if prec is not None or number != (0, 0): if number[1].is_zero and is_real: leaves.insert(0, Number.from_mp(number[0], prec)) elif number[1].is_zero and number[1].is_Integer and prec is None: leaves.insert(0, Number.from_mp(number[0], prec)) else: leaves.insert(0, Complex(number[0], number[1], prec)) if not leaves: return Integer(0) elif len(leaves) == 1: return leaves[0] else: leaves.sort() return Expression('Plus', *leaves)
def c(i, r): return Complex(MachineReal(i), MachineReal(i))
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 testAcrossTypes(self): _test_group(Integer(1), Rational(1, 1), Real(1), Complex(Integer(1), Integer(1)), String('1'), Symbol('1'))