Exemplo n.º 1
0
def _test_to_pymbolic(mapper, sym, use_symengine):
    x, y = sym.symbols("x,y")

    assert mapper(sym.Rational(3, 4)) == prim.Quotient(3, 4)
    assert mapper(sym.Integer(6)) == 6

    if not use_symengine:
        assert mapper(sym.Subs(x**2, (x,), (y,))) == \
            prim.Substitution(x_**2, ("x",), (y_,))
        deriv = sym.Derivative(x**2, x)
        assert mapper(deriv) == prim.Derivative(x_**2, ("x", ))
    else:
        assert mapper(sym.Subs(x**2, (x,), (y,))) == \
            y_**2
        deriv = sym.Derivative(x**2, x)
        assert mapper(deriv) == 2 * x_

    # functions
    assert mapper(sym.Function("f")(x)) == prim.Variable("f")(x_)
    assert mapper(sym.exp(x)) == prim.Variable("exp")(x_)

    # indexed accesses
    if not use_symengine:
        i, j = sym.symbols("i,j")
        assert mapper(sym.Indexed(x, i, j)) == x_[i_, j_]

    # constants
    import math
    # FIXME: Why isn't this exact?
    assert abs(mapper(sym.pi) - math.pi) < 1e-14
    assert abs(mapper(sym.E) - math.e) < 1e-14
    assert mapper(sym.I) == 1j
Exemplo n.º 2
0
def make_random_expression(var_values, size):
    from random import randrange
    import pymbolic.primitives as p
    v = randrange(1500)
    size[0] += 1
    if v < 500 and size[0] < 40:
        term_count = randrange(2, 5)
        if randrange(2) < 1:
            cls = p.Sum
        else:
            cls = p.Product
        return cls(
            tuple(
                make_random_expression(var_values, size)
                for i in range(term_count)))
    elif v < 750:
        return make_random_value()
    elif v < 1000:
        var_name = "var_%d" % len(var_values)
        assert var_name not in var_values
        var_values[var_name] = make_random_value()
        return p.Variable(var_name)
    elif v < 1250:
        # Cannot use '-' because that destroys numpy constants.
        return p.Sum((make_random_expression(var_values, size),
                      -make_random_expression(var_values, size)))
    elif v < 1500:
        # Cannot use '/' because that destroys numpy constants.
        return p.Quotient(make_random_expression(var_values, size),
                          make_random_expression(var_values, size))
Exemplo n.º 3
0
    def map_Rational(self, expr):
        num = self.rec(expr.p)
        denom = self.rec(expr.q)

        if prim.is_zero(denom - 1):
            return num
        return prim.Quotient(num, denom)
Exemplo n.º 4
0
    def map_Rational(self, expr):  # noqa
        p, q = expr.p, expr.q

        num = self.rec(p)
        denom = self.rec(q)

        if prim.is_zero(denom - 1):
            return num
        return prim.Quotient(num, denom)
Exemplo n.º 5
0
def make_random_fp_expression(prefix, var_values, size, use_complex):
    from random import randrange
    import pymbolic.primitives as p
    v = randrange(1500)
    size[0] += 1
    if v < 500 and size[0] < 40:
        term_count = randrange(2, 5)
        if randrange(2) < 1:
            cls = p.Sum
        else:
            cls = p.Product
        return cls(
            tuple(
                make_random_fp_expression(prefix, var_values, size,
                                          use_complex)
                for i in range(term_count)))
    elif v < 750:
        return make_random_fp_value(use_complex=use_complex)
    elif v < 1000:
        var_name = "var_%s_%d" % (prefix, len(var_values))
        assert var_name not in var_values
        var_values[var_name] = make_random_fp_value(use_complex=use_complex)
        return p.Variable(var_name)
    elif v < 1250:
        # FIXME: What does this comment mean?
        # Cannot use '-' because that destroys numpy constants.
        return p.Sum((
            make_random_fp_expression(prefix, var_values, size, use_complex),
            -make_random_fp_expression(prefix, var_values, size, use_complex)))
    elif v < 1500:
        # FIXME: What does this comment mean?
        # Cannot use '/' because that destroys numpy constants.
        return p.Quotient(
            make_random_fp_expression(prefix, var_values, size, use_complex),
            make_random_fp_expression(prefix, var_values, size, use_complex))
    else:
        assert False
Exemplo n.º 6
0
def _expression_division(expr, ctx):
    return p.Quotient(*(expression(c, ctx) for c in expr.children))
Exemplo n.º 7
0
    def parse_postfix(self, pstate, min_precedence, left_exp):
        import pymbolic.primitives as primitives

        did_something = False

        next_tag = pstate.next_tag()

        if next_tag is _openpar and _PREC_CALL > min_precedence:
            pstate.advance()
            args, kwargs = self.parse_arglist(pstate)

            if kwargs:
                left_exp = primitives.CallWithKwargs(left_exp, args, kwargs)
            else:
                left_exp = primitives.Call(left_exp, args)

            did_something = True
        elif next_tag is _openbracket and _PREC_CALL > min_precedence:
            pstate.advance()
            pstate.expect_not_end()
            left_exp = primitives.Subscript(left_exp, self.parse_expression(pstate))
            pstate.expect(_closebracket)
            pstate.advance()
            did_something = True
        elif next_tag is _if and _PREC_IF > min_precedence:
            from pymbolic.primitives import If
            then_expr = left_exp
            pstate.advance()
            pstate.expect_not_end()
            condition = self.parse_expression(pstate, _PREC_LOGICAL_OR)
            pstate.expect(_else)
            pstate.advance()
            else_expr = self.parse_expression(pstate)
            left_exp = If(condition, then_expr, else_expr)
            did_something = True
        elif next_tag is _dot and _PREC_CALL > min_precedence:
            pstate.advance()
            pstate.expect(_identifier)
            left_exp = primitives.Lookup(left_exp, pstate.next_str())
            pstate.advance()
            did_something = True
        elif next_tag is _plus and _PREC_PLUS > min_precedence:
            pstate.advance()
            right_exp = self.parse_expression(pstate, _PREC_PLUS)
            if isinstance(left_exp, primitives.Sum):
                left_exp = primitives.Sum(left_exp.children + (right_exp,))
            else:
                left_exp = primitives.Sum((left_exp, right_exp))

            did_something = True
        elif next_tag is _minus and _PREC_PLUS > min_precedence:
            pstate.advance()
            right_exp = self.parse_expression(pstate, _PREC_PLUS)
            if isinstance(left_exp, primitives.Sum):
                left_exp = primitives.Sum(left_exp.children + ((-right_exp),))  # noqa pylint:disable=invalid-unary-operand-type
            else:
                left_exp = primitives.Sum((left_exp, -right_exp))  # noqa pylint:disable=invalid-unary-operand-type
            did_something = True
        elif next_tag is _times and _PREC_TIMES > min_precedence:
            pstate.advance()
            right_exp = self.parse_expression(pstate, _PREC_PLUS)
            if isinstance(left_exp, primitives.Product):
                left_exp = primitives.Product(left_exp.children + (right_exp,))
            else:
                left_exp = primitives.Product((left_exp, right_exp))
            did_something = True
        elif next_tag is _floordiv and _PREC_TIMES > min_precedence:
            pstate.advance()
            left_exp = primitives.FloorDiv(
                    left_exp, self.parse_expression(pstate, _PREC_TIMES))
            did_something = True
        elif next_tag is _over and _PREC_TIMES > min_precedence:
            pstate.advance()
            left_exp = primitives.Quotient(
                    left_exp, self.parse_expression(pstate, _PREC_TIMES))
            did_something = True
        elif next_tag is _modulo and _PREC_TIMES > min_precedence:
            pstate.advance()
            left_exp = primitives.Remainder(
                    left_exp, self.parse_expression(pstate, _PREC_TIMES))
            did_something = True
        elif next_tag is _power and _PREC_POWER > min_precedence:
            pstate.advance()
            left_exp = primitives.Power(
                    left_exp, self.parse_expression(pstate, _PREC_TIMES))
            did_something = True
        elif next_tag is _and and _PREC_LOGICAL_AND > min_precedence:
            pstate.advance()
            from pymbolic.primitives import LogicalAnd
            left_exp = LogicalAnd((
                    left_exp,
                    self.parse_expression(pstate, _PREC_LOGICAL_AND)))
            did_something = True
        elif next_tag is _or and _PREC_LOGICAL_OR > min_precedence:
            pstate.advance()
            from pymbolic.primitives import LogicalOr
            left_exp = LogicalOr((
                    left_exp,
                    self.parse_expression(pstate, _PREC_LOGICAL_OR)))
            did_something = True
        elif next_tag is _bitwiseor and _PREC_BITWISE_OR > min_precedence:
            pstate.advance()
            from pymbolic.primitives import BitwiseOr
            left_exp = BitwiseOr((
                    left_exp,
                    self.parse_expression(pstate, _PREC_BITWISE_OR)))
            did_something = True
        elif next_tag is _bitwisexor and _PREC_BITWISE_XOR > min_precedence:
            pstate.advance()
            from pymbolic.primitives import BitwiseXor
            left_exp = BitwiseXor((
                    left_exp,
                    self.parse_expression(pstate, _PREC_BITWISE_XOR)))
            did_something = True
        elif next_tag is _bitwiseand and _PREC_BITWISE_AND > min_precedence:
            pstate.advance()
            from pymbolic.primitives import BitwiseAnd
            left_exp = BitwiseAnd((
                    left_exp,
                    self.parse_expression(pstate, _PREC_BITWISE_AND)))
            did_something = True
        elif next_tag is _rightshift and _PREC_SHIFT > min_precedence:
            pstate.advance()
            from pymbolic.primitives import RightShift
            left_exp = RightShift(
                    left_exp,
                    self.parse_expression(pstate, _PREC_SHIFT))
            did_something = True
        elif next_tag is _leftshift and _PREC_SHIFT > min_precedence:
            pstate.advance()
            from pymbolic.primitives import LeftShift
            left_exp = LeftShift(
                    left_exp,
                    self.parse_expression(pstate, _PREC_SHIFT))
            did_something = True
        elif next_tag in self._COMP_TABLE and _PREC_COMPARISON > min_precedence:
            pstate.advance()
            from pymbolic.primitives import Comparison
            left_exp = Comparison(
                    left_exp,
                    self._COMP_TABLE[next_tag],
                    self.parse_expression(pstate, _PREC_COMPARISON))
            did_something = True
        elif next_tag is _colon and _PREC_SLICE >= min_precedence:
            pstate.advance()
            expr_pstate = pstate.copy()

            assert not isinstance(left_exp, primitives.Slice)

            from pytools.lex import ParseError
            try:
                next_expr = self.parse_expression(expr_pstate, _PREC_SLICE)
            except ParseError:
                # no expression follows, too bad.
                left_exp = primitives.Slice((left_exp, None,))
            else:
                left_exp = _join_to_slice(left_exp, next_expr)
                pstate.assign(expr_pstate)

            did_something = True

        elif next_tag is _comma and _PREC_COMMA > min_precedence:
            # The precedence makes the comma left-associative.

            pstate.advance()
            if pstate.is_at_end() or pstate.next_tag() is _closepar:
                if isinstance(left_exp, (tuple, list)) \
                        and not isinstance(left_exp, FinalizedContainer):
                    # left_expr is a container with trailing commas
                    pass
                else:
                    left_exp = (left_exp,)
            else:
                new_el = self.parse_expression(pstate, _PREC_COMMA)
                if isinstance(left_exp, (tuple, list)) \
                        and not isinstance(left_exp, FinalizedContainer):
                    left_exp = left_exp + (new_el,)
                else:
                    left_exp = (left_exp, new_el)

            did_something = True

        return left_exp, did_something