Example #1
0
        def dist(prod):
            if not isinstance(prod, Product):
                return prod

            leading = []
            for i in prod.children:
                if isinstance(i, Sum):
                    break
                else:
                    leading.append(i)

            if len(leading) == len(prod.children):
                # no more sums found
                result = pymbolic.flattened_product(prod.children)
                return result
            else:
                sum = prod.children[len(leading)]
                assert isinstance(sum, Sum)
                rest = prod.children[len(leading)+1:]
                if rest:
                    rest = dist(Product(rest))
                else:
                    rest = 1

                result = self.collect(pymbolic.flattened_sum(
                       pymbolic.flattened_product(leading) * dist(sumchild*rest)
                       for sumchild in sum.children
                       ))
                return result
Example #2
0
        def expand(prod):
            if not isinstance(prod, Product):
                return prod

            leading = []
            for i in prod.children:
                if isinstance(i, Sum):
                    break
                else:
                    leading.append(i)

            if len(leading) == len(prod.children):
                # no more sums found
                result = pymbolic.flattened_product(prod.children)
                return result
            else:
                sum = prod.children[len(leading)]
                assert isinstance(sum, Sum)
                rest = prod.children[len(leading)+1:]
                if rest:
                    rest = expand(Product(rest))
                else:
                    rest = 1

                result = self.collector(pymbolic.flattened_sum(
                       pymbolic.flattened_product(leading) * expand(sumchild*rest)
                       for sumchild in sum.children
                       ))
                return result
Example #3
0
    def map_power(self, expr):
        from pymbolic.primitives import Expression, Sum

        if isinstance(expr.base, Product):
            return self.rec(pymbolic.flattened_product(
                child**expr.exponent for child in newbase))

        if isinstance(expr.exponent, int):
            newbase = self.rec(expr.base)
            if isinstance(newbase, Sum):
                return self.map_product(pymbolic.flattened_product(expr.exponent*(newbase,)))
            else:
                return IdentityMapper.map_power(self, expr)
        else:
            return IdentityMapper.map_power(self, expr)
Example #4
0
    def map_power(self, expr):
        from pymbolic.primitives import Expression, Sum

        if isinstance(expr.base, Product):
            return self.rec(pymbolic.flattened_product(
                child**expr.exponent for child in newbase))

        if isinstance(expr.exponent, int):
            newbase = self.rec(expr.base)
            if isinstance(newbase, Sum):
                return self.map_product(pymbolic.flattened_product(expr.exponent*(newbase,)))
            else:
                return IdentityMapper.map_power(self, expr)
        else:
            return IdentityMapper.map_power(self, expr)
Example #5
0
 def map_product(self, expr, *args):
     return pymbolic.flattened_sum(
         pymbolic.flattened_product(
             [self.rec_undiff(ch, *args)
              for ch in expr.children[0:i]] + [self.rec(child, *args)] +
             [self.rec_undiff(ch, *args) for ch in expr.children[i + 1:]])
         for i, child in enumerate(expr.children))
Example #6
0
 def map_product(self, expr):
     return pymbolic.flattened_sum(
         pymbolic.flattened_product(
             expr.children[0:i] +
             (self.rec(child),) +
             expr.children[i+1:])
         for i, child in enumerate(expr.children))
Example #7
0
 def map_quotient(self, expr):
     if is_zero(expr.numerator - 1):
         return expr
     else:
         # not the smartest thing we can do, but at least *something*
         return pymbolic.flattened_product([
                 type(expr)(1, self.rec(expr.denominator)),
                 self.rec(expr.numerator)])
Example #8
0
 def map_product(self, expr, *args):
     return pymbolic.flattened_sum(
         pymbolic.flattened_product(
             [self.rec_undiff(ch, *args) for ch in expr.children[0:i]] +
             [self.rec(child, *args)] +
             [self.rec_undiff(ch, *args) for ch in expr.children[i+1:]]
             )
         for i, child in enumerate(expr.children))
Example #9
0
 def map_quotient(self, expr):
     if is_zero(expr.numerator - 1):
         return expr
     else:
         # not the smartest thing we can do, but at least *something*
         return pymbolic.flattened_product([
             type(expr)(1, self.rec(expr.denominator)),
             self.rec(expr.numerator)
         ])
Example #10
0
    def split_term(self, mul_term):
        """Returns  a pair consisting of:
        - a frozenset of (base, exponent) pairs
        - a product of coefficients (i.e. constants and parameters)

        The set takes care of order-invariant comparison for us and is hashable.

        The argument `product' has to be fully expanded already.
        """
        from pymbolic.primitives import Product, Power, AlgebraicLeaf

        def base(term):
            if isinstance(term, Power):
                return term.base
            else:
                return term

        def exponent(term):
            if isinstance(term, Power):
                return term.exponent
            else:
                return 1

        if isinstance(mul_term, Product):
            terms = mul_term.children
        elif isinstance(mul_term, (Power, AlgebraicLeaf)):
            terms = [mul_term]
        elif not bool(self.get_dependencies(mul_term)):
            terms = [mul_term]
        else:
            raise RuntimeError("split_term expects a multiplicative term")

        base2exp = {}
        for term in terms:
            mybase = base(term)
            myexp = exponent(term)

            if mybase in base2exp:
                base2exp[mybase] += myexp
            else:
                base2exp[mybase] = myexp

        coefficients = []
        cleaned_base2exp = {}
        for base, exp in six.iteritems(base2exp):
            term = base**exp
            if self.get_dependencies(term) <= self.parameters:
                coefficients.append(term)
            else:
                cleaned_base2exp[base] = exp

        term = frozenset(
            (base, exp) for base, exp in six.iteritems(cleaned_base2exp))
        return term, self.rec(pymbolic.flattened_product(coefficients))
Example #11
0
    def split_term(self, mul_term):
        """Returns  a pair consisting of:
        - a frozenset of (base, exponent) pairs
        - a product of coefficients (i.e. constants and parameters)

        The set takes care of order-invariant comparison for us and is hashable.

        The argument `product' has to be fully expanded already.
        """
        from pymbolic.primitives import Product, Power, AlgebraicLeaf

        def base(term):
            if isinstance(term, Power):
                return term.base
            else:
                return term

        def exponent(term):
            if isinstance(term, Power):
                return term.exponent
            else:
                return 1

        if isinstance(mul_term, Product):
            terms = mul_term.children
        elif isinstance(mul_term, (Power, AlgebraicLeaf)):
            terms = [mul_term]
        elif not bool(self.get_dependencies(mul_term)):
            terms = [mul_term]
        else:
            raise RuntimeError("split_term expects a multiplicative term")

        base2exp = {}
        for term in terms:
            mybase = base(term)
            myexp = exponent(term)

            if mybase in base2exp:
                base2exp[mybase] += myexp
            else:
                base2exp[mybase] = myexp

        coefficients = []
        cleaned_base2exp = {}
        for base, exp in six.iteritems(base2exp):
            term = base**exp
            if self.get_dependencies(term) <= self.parameters:
                coefficients.append(term)
            else:
                cleaned_base2exp[base] = exp

        term = frozenset(
                (base, exp) for base, exp in six.iteritems(cleaned_base2exp))
        return term, self.rec(pymbolic.flattened_product(coefficients))
Example #12
0
 def rep2term(rep):
     return pymbolic.flattened_product(base**exp for base, exp in rep)
Example #13
0
 def map_product(self, expr):
     return pymbolic.flattened_sum(
         pymbolic.flattened_product(expr.children[0:i] +
                                    (self.rec(child), ) +
                                    expr.children[i + 1:])
         for i, child in enumerate(expr.children))
Example #14
0
 def rep2term(rep):
     return pymbolic.flattened_product(base**exp for base, exp in rep)