# loki.expression.symbolic module

is_constant(expr)

  Return True if the given expression reduces to a constant value, else return False.

symbolic_op(expr1, op, expr2)

  Evaluate expr1 <op> expr2 (or equivalently, op(expr1, expr2)) and return the result.

  op can be any binary operation such as the rich comparison operators from the operator library.

  While calling this function largely equivalent to applying the operator directly, it is to be understood as a convenience layer that applies, depending on the operator, a number of symbolically neutral manipulations. Currently, this only applies to comparison operators (such as eq, ne, lt, `le, gt, ge). Since expression nodes do not imply an order, such comparisons would fail even if a symbolic meaning can be derived.

  For that reason, these operations are reformulated as the difference between the two expressions and compared against 0. For example: `` # n < n + 1 Scalar('n') < Sum((Scalar('n'), IntLiteral(1))) `` raises a TypeError but `` # n < n + 1 symbolic_op(Scalar('n'), operator.lt, Sum((Scalar('n'), IntLiteral(1)))) `` returns True.

  This is done by transforming this expression into `` # n - (n + 1) < 0 Sum((Scalar('n'), Product(-1, Sum((Scalar('n'), IntLiteral(1)))))) < 0 `` and then calling simplify on the left hand side to obtain `` # -1 < 0 Product(-1, IntLiteral(1)) < 0 `` In combination with stripping the minus prefix this yields the result.

simplify(expr, enabled_simplifications=<Simplification.ALL: 15>)

  Simplify the given expression by applying selected simplifications.

accumulate_polynomial_terms(expr)

  Collect all occurences of each base and determine the constant coefficient in a list of expressions.

  Note that this works for any non-constant sub-expression as “base” for summands and thus this can be applied not only to polynomials.

  Parameters:

    components (list) – list of expressions, e.g., components of a `sym.Sum`.

  Returns:

    mapping of base and corresponding coefficient

  Return type:

    dict

class Simplification(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

  Bases: `Flag`

  The selection of available simplification techniques that can be used to simplify expressions. Multiple techniques can be combined using bitwise logical operations, for example: `` Flatten | IntegerArithmetic ALL & ~Flatten ``

  Flatten Flatten sub-sums and distribute products.
  IntegerArithmetic Perform arithmetic on integer literals
    Type:

      addition and multiplication

  CollectCoefficients Combine summands as far as possible.
  LogicEvaluation Resolve logically fully determinate expressions, like ``1 == 1`` or ``1 == 6``
  ALL All of the above.
  Flatten = 1
  IntegerArithmetic = 2
  CollectCoefficients = 4
  LogicEvaluation = 8
  ALL = 15

class SimplifyMapper(enabled_simplifications=<Simplification.ALL: 15>)

  Bases: `LokiIdentityMapper`

  A mapper that attempts to symbolically simplify an expression.

  It applies all enabled simplifications from Simplification to a expression.

  map_sum(expr, *args, **kwargs)
  map_product(expr, *args, **kwargs)
  map_quotient(expr, *args, **kwargs)
  map_parenthesised_add(expr, *args, **kwargs)
  map_parenthesised_mul(expr, *args, **kwargs)
  map_parenthesised_div(expr, *args, **kwargs)
  map_comparison(expr, *args, **kwargs)
  map_logical_and(expr, *args, **kwargs)
  map_logical_or(expr, *args, **kwargs)

is_dimension_constant(d)

  Establish if a given dimension symbol is a compile-time constant

ceil_division(iexpr1: Expression, iexpr2: Expression) → Expression

  Returns ceiled division expression of two integer expressions iexpr1/iexpr2.

get_pyrange(loop_range: LoopRange)

  Returns a python range corresponding to a LoopRange of IntLiterals.

iteration_number(iter_idx, loop_range: LoopRange) → Expression

  Returns the normalized iteration number of the iteration variable

  Given the loop iteration index for an iteration in a loop defined by the :any:´LoopRange´ this method returns the normalized iteration index given by iter_num = (iter_idx - start + step)/step = (iter_idx-start)/step + 1

  Parameters:

    - iter_idx (`Variable`, `Expression`, or `IntLiteral`) – corresponding to a valid iteration index for the parameter loop_range

    - loop_range (`LoopRange`)

iteration_index(iter_num, loop_range: LoopRange) → Expression

  Returns the iteration index of the loop based on the iteration number

  Given the normalized iteration number for an iteration in a loop defined by the :any:´LoopRange´ this method returns the iteration index given by iter_idx = (iter_num-1)*step+start

  Parameters:

    - iter_num (`Variable`, `Expression`, or `sym.IntLiteral`) – corresponding to a valid iteration number for the parameter loop_range

    - loop_range (`LoopRange`)