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
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))
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)
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)
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
def _expression_division(expr, ctx): return p.Quotient(*(expression(c, ctx) for c in expr.children))
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