示例#1
0
    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)
示例#2
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))
示例#3
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))
示例#4
0
文件: numeric.py 项目: chid/Mathics
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
示例#5
0
    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)
示例#6
0
    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)
示例#7
0
 def evaluate(self, evaluation):
     return Complex(Integer(0), Integer(1))
示例#8
0
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)
示例#9
0
 def evaluate(self, evaluation):
     return Complex(Integer0, Integer1)
示例#10
0
    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)
示例#11
0
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__)))
示例#12
0
 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')))))
示例#13
0
 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))
示例#14
0
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)
示例#15
0
 def evaluate(self, evaluation):
     return Complex(mpz(0), mpz(1))
示例#16
0
 def evaluate(self, evaluation):
     return Complex(sympy.Integer(0), sympy.Integer(1))
示例#17
0
    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)
示例#18
0
 def c(i, r):
     return Complex(MachineReal(i), MachineReal(i))
示例#19
0
    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())
示例#20
0
 def testAcrossTypes(self):
     _test_group(Integer(1), Rational(1, 1), Real(1),
                 Complex(Integer(1), Integer(1)), String('1'), Symbol('1'))