コード例 #1
0
 def _coeff_det(coeff, j):
     return Product((coeff if j % 2 == 0 else -coeff,
                     Call(self, (_minor(array, 0, j), ))))
コード例 #2
0
    def parse_postfix(self, pstate, min_precedence, left_exp):
        import pymbolic.primitives as primitives
        import pymbolic.parser as p

        did_something = False

        next_tag = pstate.next_tag()

        if next_tag is p._openpar and p._PREC_CALL > min_precedence:
            pstate.advance()
            pstate.expect_not_end()
            if next_tag is p._closepar:
                pstate.advance()
                left_exp = primitives.Call(left_exp, ())
            else:
                args = self.parse_expression(pstate)
                if not isinstance(args, tuple):
                    args = (args, )

                pstate.expect(p._closepar)
                pstate.advance()

                if left_exp == primitives.Variable("matrix"):
                    left_exp = np.array(list(list(row) for row in args))
                else:
                    left_exp = primitives.Call(left_exp, args)

            did_something = True
        elif next_tag is p._openbracket and p._PREC_CALL > min_precedence:
            pstate.advance()
            pstate.expect_not_end()
            left_exp = primitives.Subscript(left_exp,
                                            self.parse_expression(pstate))
            pstate.expect(p._closebracket)
            pstate.advance()
            did_something = True
        elif next_tag is p._dot and p._PREC_CALL > min_precedence:
            pstate.advance()
            pstate.expect(p._identifier)
            left_exp = primitives.Lookup(left_exp, pstate.next_str())
            pstate.advance()
            did_something = True
        elif next_tag is p._plus and p._PREC_PLUS > min_precedence:
            pstate.advance()
            left_exp += self.parse_expression(pstate, p._PREC_PLUS)
            did_something = True
        elif next_tag is p._minus and p._PREC_PLUS > min_precedence:
            pstate.advance()
            left_exp -= self.parse_expression(pstate, p._PREC_PLUS)
            did_something = True
        elif next_tag is p._times and p._PREC_TIMES > min_precedence:
            pstate.advance()
            left_exp *= self.parse_expression(pstate, p._PREC_TIMES)
            did_something = True
        elif next_tag is p._over and p._PREC_TIMES > min_precedence:
            pstate.advance()
            from pymbolic.primitives import Quotient
            left_exp = Quotient(left_exp,
                                self.parse_expression(pstate, p._PREC_TIMES))
            did_something = True
        elif next_tag is self.power_sym and p._PREC_POWER > min_precedence:
            pstate.advance()
            exponent = self.parse_expression(pstate, p._PREC_POWER)
            if left_exp == np.e:
                from pymbolic.primitives import Call, Variable
                left_exp = Call(Variable("exp"), (exponent, ))
            else:
                left_exp **= exponent
            did_something = True
        elif next_tag is p._comma and p._PREC_COMMA > min_precedence:
            # The precedence makes the comma left-associative.

            pstate.advance()
            if pstate.is_at_end() or pstate.next_tag() is p._closepar:
                left_exp = (left_exp, )
            else:
                new_el = self.parse_expression(pstate, p._PREC_COMMA)
                if isinstance(left_exp, tuple) \
                        and not isinstance(left_exp, FinalizedTuple):
                    left_exp = left_exp + (new_el, )
                else:
                    left_exp = (left_exp, new_el)

            did_something = True

        return left_exp, did_something
コード例 #3
0
ファイル: array.py プロジェクト: kaushikcfd/numloopy
    def _arithmetic_op(self, other, op):
        """
        Registers a substitution rule that performs ``(self) op (other)``
        element-wise for the arrays. :mod:`numpy` broadcasting rules are
        followed while performing these operations.

        :return: An instance of :class:`ArraySymbol` corresponding to the
            registered substitution for the element-wise operation.
        """
        assert op in ['+', '-', '*', '/', '<', '<=', '>', '>=']
        assert self.stack == other.stack

        def _apply_op(var1, var2):
            if op == '+':
                return var1 + var2, self.dtype
            if op == '-':
                return var1 - var2, self.dtype
            if op == '*':
                return var1 * var2, self.dtype
            if op == '/':
                return var1 / var2, self.dtype
            if op == '<':
                return var1.lt(var2), np.int
            if op == '<=':
                return var1.le(var2), np.int
            if op == '>':
                return var1.gt(var2), np.int
            if op == '>=':
                return var1.ge(var2), np.int
            raise RuntimeError()

        if isinstance(other, Number):
            inames = tuple(
                self.stack.name_generator(based_on='i') for _ in self.shape)
            rhs, dtype = _apply_op(
                Call(function=Variable(self.name),
                     parameters=tuple(Variable(iname) for iname in inames)),
                other)
            subst_name = self.stack.name_generator(based_on='subst')
            self.stack.register_substitution(
                lp.SubstitutionRule(subst_name, inames, rhs))
            return self.copy(name=subst_name, dtype=dtype)
        elif isinstance(other, ArraySymbol):
            if self.shape == other.shape:
                inames = tuple(
                    self.stack.name_generator(based_on='i')
                    for _ in self.shape)
                rhs, dtype = _apply_op(
                    Variable(self.name)(*tuple(
                        Variable(iname) for iname in inames)),
                    Variable(other.name)(*tuple(
                        Variable(iname) for iname in inames)))
                subst_name = self.stack.name_generator(based_on='subst')
                self.stack.register_substitution(
                    lp.SubstitutionRule(subst_name, inames, rhs))
                return self.copy(name=subst_name, dtype=dtype)
            else:
                left = self
                right = other
                new_left_shape = self.shape[:]
                new_right_shape = other.shape[:]
                if len(left.shape) > len(right.shape):
                    new_right_shape = ((1, ) *
                                       (len(left.shape) - len(right.shape)) +
                                       new_right_shape)
                if len(left.shape) < len(right.shape):
                    new_left_shape = ((1, ) *
                                      (len(right.shape) - len(left.shape)) +
                                      new_left_shape)

                # now both have the same shapes
                # let compute the shape of these guys
                new_shape = [1] * len(new_left_shape)

                for i, (left_len, right_len) in enumerate(
                        zip(new_left_shape, new_right_shape)):
                    if left_len == right_len:
                        new_shape[i] = left_len
                    else:
                        if left_len != 1 and right_len != 1:
                            raise ValueError("Cannot be broadcasted.")
                        else:
                            new_shape[i] = left_len * right_len

                new_shape = tuple(new_shape)

                if new_shape != left.shape:
                    subst_name = self.stack.name_generator(based_on="subst")
                    inames = tuple(
                        self.stack.name_generator(based_on="i")
                        for _ in new_left_shape)

                    def _empty_if_zero(_idx):
                        if _idx == (0, ):
                            return ()
                        return _idx

                    indices = _empty_if_zero(
                        tuple(
                            Variable(iname) if axis_len != 1 else 0
                            for iname, axis_len in zip(
                                inames[-len(left.shape):], left.shape)))
                    rule = lp.SubstitutionRule(subst_name, inames,
                                               Variable(left.name)(*indices))
                    self.stack.register_substitution(rule)
                    new_left = left.copy(name=subst_name,
                                         shape=new_shape,
                                         dim_tags=None,
                                         order=left.order)
                else:
                    new_left = left

                if new_shape != right.shape:
                    subst_name = self.stack.name_generator(based_on="subst")
                    inames = tuple(
                        self.stack.name_generator(based_on="i")
                        for _ in new_right_shape)

                    def _empty_if_zero(_idx):
                        if _idx == (0, ):
                            return ()
                        return _idx

                    indices = _empty_if_zero(
                        tuple(
                            Variable(iname) if axis_len != 1 else 0
                            for iname, axis_len in zip(
                                inames[-len(right.shape):], right.shape)))
                    rule = lp.SubstitutionRule(subst_name, inames,
                                               Variable(right.name)(*indices))
                    self.stack.register_substitution(rule)
                    new_right = right.copy(name=subst_name,
                                           shape=new_shape,
                                           dim_tags=None,
                                           order=right.order)
                else:
                    new_right = right

                return new_left._arithmetic_op(new_right, op)

        else:
            raise NotImplementedError('__mul__ for', type(other))