示例#1
0
    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)
示例#2
0
    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)
示例#3
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_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)
示例#4
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_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)