Exemplo n.º 1
0
    def _eval_derivative_matrix_lines(self, x):
        from sympy.tensor.array.expressions.array_expressions import ArrayTensorProduct
        from sympy.tensor.array.expressions.array_expressions import ArrayDiagonal
        from sympy.matrices.expressions.matexpr import _make_matrix

        lr = self.base._eval_derivative_matrix_lines(x)
        for i in lr:
            diagonal = [(1, 2), (3, 4)]
            diagonal = [e for j, e in enumerate(diagonal) if self.base.shape[j] != 1]
            l1 = i._lines[i._first_line_index]
            l2 = i._lines[i._second_line_index]
            subexpr = ExprBuilder(
                ArrayDiagonal,
                [
                    ExprBuilder(
                        ArrayTensorProduct,
                        [
                            ExprBuilder(_make_matrix, [l1]),
                            self.exp*hadamard_power(self.base, self.exp-1),
                            ExprBuilder(_make_matrix, [l2]),
                        ]
                    ),
                *diagonal],
                validator=ArrayDiagonal._validate
            )
            i._first_pointer_parent = subexpr.args[0].args[0].args
            i._first_pointer_index = 0
            i._first_line_index = 0
            i._second_pointer_parent = subexpr.args[0].args[2].args
            i._second_pointer_index = 0
            i._second_line_index = 0
            i._lines = [subexpr]
        return lr
Exemplo n.º 2
0
    def _eval_derivative_matrix_lines(self, x):
        from sympy.codegen.array_utils import CodegenArrayTensorProduct
        from sympy.codegen.array_utils import CodegenArrayContraction, CodegenArrayDiagonal
        from sympy.core.expr import ExprBuilder
        from sympy.matrices.expressions.matexpr import _make_matrix

        lr = self.base._eval_derivative_matrix_lines(x)
        for i in lr:
            diagonal = [(1, 2), (3, 4)]
            diagonal = [e for j, e in enumerate(diagonal) if self.base.shape[j] != 1]
            l1 = i._lines[i._first_line_index]
            l2 = i._lines[i._second_line_index]
            subexpr = ExprBuilder(
                CodegenArrayDiagonal,
                [
                    ExprBuilder(
                        CodegenArrayTensorProduct,
                        [
                            ExprBuilder(_make_matrix, [l1]),
                            self.exp*hadamard_power(self.base, self.exp-1),
                            ExprBuilder(_make_matrix, [l2]),
                        ]
                    ),
                ] + diagonal,  # turn into *diagonal after dropping Python 2.7
                validator=CodegenArrayDiagonal._validate
            )
            i._first_pointer_parent = subexpr.args[0].args[0].args
            i._first_pointer_index = 0
            i._first_line_index = 0
            i._second_pointer_parent = subexpr.args[0].args[2].args
            i._second_pointer_index = 0
            i._second_line_index = 0
            i._lines = [subexpr]
        return lr
Exemplo n.º 3
0
 def _eval_derivative_matrix_lines(self, x):
     from sympy.codegen.array_utils import CodegenArrayContraction, CodegenArrayTensorProduct
     from sympy.core.expr import ExprBuilder
     r = self.args[0]._eval_derivative_matrix_lines(x)
     for lr in r:
         if lr.higher == 1:
             lr.higher = ExprBuilder(
                 CodegenArrayContraction, [
                     ExprBuilder(CodegenArrayTensorProduct, [
                         lr._lines[0],
                         lr._lines[1],
                     ]),
                     (1, 3),
                 ],
                 validator=CodegenArrayContraction._validate)
         else:
             # This is not a matrix line:
             lr.higher = ExprBuilder(CodegenArrayContraction, [
                 ExprBuilder(CodegenArrayTensorProduct, [
                     lr._lines[0],
                     lr._lines[1],
                     lr.higher,
                 ]), (1, 3), (0, 2)
             ])
         lr._lines = [S.One, S.One]
         lr._first_pointer_parent = lr._lines
         lr._second_pointer_parent = lr._lines
         lr._first_pointer_index = 0
         lr._second_pointer_index = 1
     return r
Exemplo n.º 4
0
    def _eval_derivative_matrix_lines(self, x):
        from sympy import Identity
        from sympy.codegen.array_utils import CodegenArrayContraction, CodegenArrayTensorProduct, CodegenArrayDiagonal
        from sympy.core.expr import ExprBuilder

        d = Dummy("d")
        function = self.function(d)
        fdiff = function.diff(d)
        if isinstance(fdiff, Function):
            fdiff = type(fdiff)
        else:
            fdiff = Lambda(d, fdiff)
        lr = self.expr._eval_derivative_matrix_lines(x)
        ewdiff = ElementwiseApplyFunction(fdiff, self.expr)
        if 1 in x.shape:
            # Vector:
            iscolumn = self.shape[1] == 1
            for i in lr:
                if iscolumn:
                    ptr1 = i.first_pointer
                    ptr2 = Identity(self.shape[1])
                else:
                    ptr1 = Identity(self.shape[0])
                    ptr2 = i.second_pointer

                subexpr = ExprBuilder(CodegenArrayDiagonal, [
                    ExprBuilder(CodegenArrayTensorProduct, [
                        ewdiff,
                        ptr1,
                        ptr2,
                    ]), (0, 2) if iscolumn else (1, 4)
                ],
                                      validator=CodegenArrayDiagonal._validate)
                i._lines = [subexpr]
                i._first_pointer_parent = subexpr.args[0].args
                i._first_pointer_index = 1
                i._second_pointer_parent = subexpr.args[0].args
                i._second_pointer_index = 2
        else:
            # Matrix case:
            for i in lr:
                ptr1 = i.first_pointer
                ptr2 = i.second_pointer
                newptr1 = Identity(ptr1.shape[1])
                newptr2 = Identity(ptr2.shape[1])
                subexpr = ExprBuilder(
                    CodegenArrayContraction, [
                        ExprBuilder(CodegenArrayTensorProduct,
                                    [ptr1, newptr1, ewdiff, ptr2, newptr2]),
                        (1, 2, 4),
                        (5, 7, 8),
                    ],
                    validator=CodegenArrayContraction._validate)
                i._first_pointer_parent = subexpr.args[0].args
                i._first_pointer_index = 1
                i._second_pointer_parent = subexpr.args[0].args
                i._second_pointer_index = 4
                i._lines = [subexpr]
        return lr
Exemplo n.º 5
0
    def _multiply_pointer(self, pointer, other):
        from sympy.core.expr import ExprBuilder
        from sympy.codegen.array_utils import CodegenArrayContraction, CodegenArrayTensorProduct

        subexpr = ExprBuilder(
            CodegenArrayContraction,
            [ExprBuilder(CodegenArrayTensorProduct, [pointer, other]), (1, 2)],
            validator=CodegenArrayContraction._validate)

        return subexpr
Exemplo n.º 6
0
    def _multiply_pointer(self, pointer, other):
        from ...tensor.array.expressions.array_expressions import ArrayTensorProduct
        from ...tensor.array.expressions.array_expressions import ArrayContraction

        subexpr = ExprBuilder(
            ArrayContraction,
            [ExprBuilder(ArrayTensorProduct, [pointer, other]), (1, 2)],
            validator=ArrayContraction._validate)

        return subexpr
Exemplo n.º 7
0
    def _eval_derivative_matrix_lines(self, x):
        from sympy import Identity
        from sympy.tensor.array.expressions.array_expressions import ArrayContraction
        from sympy.tensor.array.expressions.array_expressions import ArrayDiagonal
        from sympy.tensor.array.expressions.array_expressions import ArrayTensorProduct
        from sympy.core.expr import ExprBuilder

        fdiff = self._get_function_fdiff()
        lr = self.expr._eval_derivative_matrix_lines(x)
        ewdiff = ElementwiseApplyFunction(fdiff, self.expr)
        if 1 in x.shape:
            # Vector:
            iscolumn = self.shape[1] == 1
            for i in lr:
                if iscolumn:
                    ptr1 = i.first_pointer
                    ptr2 = Identity(self.shape[1])
                else:
                    ptr1 = Identity(self.shape[0])
                    ptr2 = i.second_pointer

                subexpr = ExprBuilder(ArrayDiagonal, [
                    ExprBuilder(ArrayTensorProduct, [
                        ewdiff,
                        ptr1,
                        ptr2,
                    ]), (0, 2) if iscolumn else (1, 4)
                ],
                                      validator=ArrayDiagonal._validate)
                i._lines = [subexpr]
                i._first_pointer_parent = subexpr.args[0].args
                i._first_pointer_index = 1
                i._second_pointer_parent = subexpr.args[0].args
                i._second_pointer_index = 2
        else:
            # Matrix case:
            for i in lr:
                ptr1 = i.first_pointer
                ptr2 = i.second_pointer
                newptr1 = Identity(ptr1.shape[1])
                newptr2 = Identity(ptr2.shape[1])
                subexpr = ExprBuilder(ArrayContraction, [
                    ExprBuilder(ArrayTensorProduct,
                                [ptr1, newptr1, ewdiff, ptr2, newptr2]),
                    (1, 2, 4),
                    (5, 7, 8),
                ],
                                      validator=ArrayContraction._validate)
                i._first_pointer_parent = subexpr.args[0].args
                i._first_pointer_index = 1
                i._second_pointer_parent = subexpr.args[0].args
                i._second_pointer_index = 4
                i._lines = [subexpr]
        return lr
Exemplo n.º 8
0
    def _eval_derivative_matrix_lines(self, x):
        from sympy.core.expr import ExprBuilder
        from sympy.codegen.array_utils import (
            CodegenArrayContraction,
            CodegenArrayTensorProduct,
        )
        from .matmul import MatMul
        from .inverse import Inverse

        exp = self.exp
        if self.base.shape == (1, 1) and not exp.has(x):
            lr = self.base._eval_derivative_matrix_lines(x)
            for i in lr:
                subexpr = ExprBuilder(
                    CodegenArrayContraction,
                    [
                        ExprBuilder(
                            CodegenArrayTensorProduct,
                            [
                                Identity(1),
                                i._lines[0],
                                exp * self.base**(exp - 1),
                                i._lines[1],
                                Identity(1),
                            ],
                        ),
                        (0, 3, 4),
                        (5, 7, 8),
                    ],
                    validator=CodegenArrayContraction._validate,
                )
                i._first_pointer_parent = subexpr.args[0].args
                i._first_pointer_index = 0
                i._second_pointer_parent = subexpr.args[0].args
                i._second_pointer_index = 4
                i._lines = [subexpr]
            return lr
        if (exp > 0) == True:
            newexpr = MatMul.fromiter([self.base for i in range(exp)])
        elif (exp == -1) == True:
            return Inverse(self.base)._eval_derivative_matrix_lines(x)
        elif (exp < 0) == True:
            newexpr = MatMul.fromiter(
                [Inverse(self.base) for i in range(-exp)])
        elif (exp == 0) == True:
            return self.doit()._eval_derivative_matrix_lines(x)
        else:
            raise NotImplementedError("cannot evaluate %s derived by %s" %
                                      (self, x))
        return newexpr._eval_derivative_matrix_lines(x)
Exemplo n.º 9
0
    def _eval_derivative_matrix_lines(self, x):
        from sympy.core.expr import ExprBuilder
        from sympy.codegen.array_utils import (
            CodegenArrayDiagonal,
            CodegenArrayTensorProduct,
        )
        from sympy.matrices.expressions.matexpr import _make_matrix

        with_x_ind = [i for i, arg in enumerate(self.args) if arg.has(x)]
        lines = []
        for ind in with_x_ind:
            left_args = self.args[:ind]
            right_args = self.args[ind + 1 :]

            d = self.args[ind]._eval_derivative_matrix_lines(x)
            hadam = hadamard_product(*(right_args + left_args))
            diagonal = [(0, 2), (3, 4)]
            diagonal = [e for j, e in enumerate(diagonal) if self.shape[j] != 1]
            for i in d:
                l1 = i._lines[i._first_line_index]
                l2 = i._lines[i._second_line_index]
                subexpr = ExprBuilder(
                    CodegenArrayDiagonal,
                    [
                        ExprBuilder(
                            CodegenArrayTensorProduct,
                            [
                                ExprBuilder(_make_matrix, [l1]),
                                hadam,
                                ExprBuilder(_make_matrix, [l2]),
                            ],
                        ),
                        *diagonal,
                    ],
                )
                i._first_pointer_parent = subexpr.args[0].args[0].args
                i._first_pointer_index = 0
                i._second_pointer_parent = subexpr.args[0].args[2].args
                i._second_pointer_index = 0
                i._lines = [subexpr]
                lines.append(i)

        return lines
Exemplo n.º 10
0
    def _eval_derivative_matrix_lines(self, x):
        from sympy import HadamardProduct, hadamard_product, Mul, MatMul, Identity, Transpose
        from sympy.matrices.expressions.diagonal import diagonalize_vector
        from sympy.matrices.expressions.matmul import validate as matmul_validate
        from sympy.core.expr import ExprBuilder

        d = Dummy("d")
        function = self.function(d)
        fdiff = function.fdiff()
        if isinstance(fdiff, Function):
            fdiff = type(fdiff)
        else:
            fdiff = Lambda(d, fdiff)
        lr = self.expr._eval_derivative_matrix_lines(x)
        ewdiff = ElementwiseApplyFunction(fdiff, self.expr)
        if 1 in x.shape:
            # Vector:
            iscolumn = self.shape[1] == 1
            ewdiff = diagonalize_vector(ewdiff)
            # TODO: check which axis is not 1
            for i in lr:
                if iscolumn:
                    ptr1 = [i.first_pointer]
                    ptr2 = [Identity(ewdiff.shape[0])]
                else:
                    ptr1 = [Identity(ewdiff.shape[1])]
                    ptr2 = [i.second_pointer]

                # TODO: check if pointers point to two different lines:

                def mul(*args):
                    return Mul.fromiter(args)

                def hadamard_or_mul(arg1, arg2):
                    if arg1.shape == arg2.shape:
                        return hadamard_product(arg1, arg2)
                    elif arg1.shape[1] == arg2.shape[0]:
                        return MatMul(arg1, arg2).doit()
                    elif arg1.shape[0] == arg2.shape[0]:
                        return MatMul(arg2.T, arg1).doit()
                    raise NotImplementedError

                i._lines = [[
                    hadamard_or_mul, [[mul, [ewdiff, ptr1[0]]], ptr2[0]]
                ]]
                i._first_pointer_parent = i._lines[0][1][0][1]
                i._first_pointer_index = 1
                i._second_pointer_parent = i._lines[0][1]
                i._second_pointer_index = 1

        else:
            # Matrix case:
            for i in lr:
                ptr1 = [i.first_pointer]
                ptr2 = [i.second_pointer]
                newptr1 = Identity(ptr1[0].shape[1])
                newptr2 = Identity(ptr2[0].shape[1])
                subexpr1 = ExprBuilder(
                    MatMul,
                    [ptr1[0],
                     ExprBuilder(diagonalize_vector, [newptr1])],
                    validator=matmul_validate,
                )
                subexpr2 = ExprBuilder(
                    Transpose,
                    [
                        ExprBuilder(
                            MatMul,
                            [
                                ptr2[0],
                                ExprBuilder(diagonalize_vector, [newptr2]),
                            ],
                        )
                    ],
                    validator=matmul_validate,
                )
                i.first_pointer = subexpr1
                i.second_pointer = subexpr2
                i._first_pointer_parent = subexpr1.args[1].args
                i._first_pointer_index = 0
                i._second_pointer_parent = subexpr2.args[0].args[1].args
                i._second_pointer_index = 0
                # TODO: check if pointers point to two different lines:

                # Unify lines:
                l = i._lines
                # TODO: check nested fucntions, e.g. log(sin(...)), the second function should be a scalar one.
                i._lines = [
                    ExprBuilder(MatMul, [l[0], ewdiff, l[1]],
                                validator=matmul_validate)
                ]
        return lr