コード例 #1
0
ファイル: matadd.py プロジェクト: zabatistas/sympy
    def __new__(cls, *args, **kwargs):
        args = list(map(sympify, args))
        check = kwargs.get('check', False)

        obj = Basic.__new__(cls, *args)
        if check:
            if all(not isinstance(i, MatrixExpr) for i in args):
                return Add.fromiter(args)
            validate(*args)
        return obj
コード例 #2
0
ファイル: matadd.py プロジェクト: cmarqu/sympy
    def __new__(cls, *args, **kwargs):
        args = list(map(sympify, args))
        check = kwargs.get('check', False)

        obj = Basic.__new__(cls, *args)
        if check:
            if all(not isinstance(i, MatrixExpr) for i in args):
                return Add.fromiter(args)
            validate(*args)
        return obj
コード例 #3
0
def _matrix_derivative(expr, x):
    from sympy import Derivative
    lines = expr._eval_derivative_matrix_lines(x)

    ranks = [i.rank() for i in lines]
    assert len(set(ranks)) == 1
    rank = ranks[0]

    if rank <= 2:
        return Add.fromiter([i.matrix_form() for i in lines])

    return Derivative(expr, x)
コード例 #4
0
    def __new__(cls, *args, **kwargs):
        if not args:
            return GenericZeroMatrix()

        # This must be removed aggressively in the constructor to avoid
        # TypeErrors from GenericZeroMatrix().shape
        args = filter(lambda i: GenericZeroMatrix() != i, args)
        args = list(map(sympify, args))
        check = kwargs.get('check', False)

        obj = Basic.__new__(cls, *args)
        if check:
            if all(not isinstance(i, MatrixExpr) for i in args):
                return Add.fromiter(args)
            validate(*args)
        return obj
コード例 #5
0
ファイル: matadd.py プロジェクト: asmeurer/sympy
    def __new__(cls, *args, **kwargs):
        if not args:
            return GenericZeroMatrix()

        # This must be removed aggressively in the constructor to avoid
        # TypeErrors from GenericZeroMatrix().shape
        args = filter(lambda i: GenericZeroMatrix() != i, args)
        args = list(map(sympify, args))
        check = kwargs.get('check', False)

        obj = Basic.__new__(cls, *args)
        if check:
            if all(not isinstance(i, MatrixExpr) for i in args):
                return Add.fromiter(args)
            validate(*args)
        return obj
コード例 #6
0
def _matrix_derivative(expr, x):
    from sympy import Derivative

    lines = expr._eval_derivative_matrix_lines(x)

    parts = [i.build() for i in lines]

    from sympy.codegen.array_utils import recognize_matrix_expression

    parts = [[recognize_matrix_expression(j).doit() for j in i] for i in parts]

    def _get_shape(elem):
        if isinstance(elem, MatrixExpr):
            return elem.shape
        return (1, 1)

    def get_rank(parts):
        return sum([j not in (1, None) for i in parts for j in _get_shape(i)])

    ranks = [get_rank(i) for i in parts]
    rank = ranks[0]

    def contract_one_dims(parts):
        if len(parts) == 1:
            return parts[0]
        else:
            p1, p2 = parts[:2]
            if p2.is_Matrix:
                p2 = p2.T
            if p1 == Identity(1):
                pbase = p2
            elif p2 == Identity(1):
                pbase = p1
            else:
                pbase = p1 * p2
            if len(parts) == 2:
                return pbase
            else:  # len(parts) > 2
                if pbase.is_Matrix:
                    raise ValueError("")
                return pbase * Mul.fromiter(parts[2:])

    if rank <= 2:
        return Add.fromiter([contract_one_dims(i) for i in parts])

    return Derivative(expr, x)
コード例 #7
0
def _matrix_derivative(expr, x):
    from sympy.tensor.array.array_derivatives import ArrayDerivative
    lines = expr._eval_derivative_matrix_lines(x)

    parts = [i.build() for i in lines]

    from sympy.tensor.array.expressions.conv_array_to_matrix import convert_array_to_matrix

    parts = [[convert_array_to_matrix(j) for j in i] for i in parts]

    def _get_shape(elem):
        if isinstance(elem, MatrixExpr):
            return elem.shape
        return 1, 1

    def get_rank(parts):
        return sum([j not in (1, None) for i in parts for j in _get_shape(i)])

    ranks = [get_rank(i) for i in parts]
    rank = ranks[0]

    def contract_one_dims(parts):
        if len(parts) == 1:
            return parts[0]
        else:
            p1, p2 = parts[:2]
            if p2.is_Matrix:
                p2 = p2.T
            if p1 == Identity(1):
                pbase = p2
            elif p2 == Identity(1):
                pbase = p1
            else:
                pbase = p1 * p2
            if len(parts) == 2:
                return pbase
            else:  # len(parts) > 2
                if pbase.is_Matrix:
                    raise ValueError("")
                return pbase * Mul.fromiter(parts[2:])

    if rank <= 2:
        return Add.fromiter([contract_one_dims(i) for i in parts])

    return ArrayDerivative(expr, x)
コード例 #8
0
ファイル: matexpr.py プロジェクト: bjodah/sympy
def _matrix_derivative(expr, x):
    from sympy import Derivative
    lines = expr._eval_derivative_matrix_lines(x)

    parts = [i.build() for i in lines]

    from sympy.codegen.array_utils import recognize_matrix_expression

    parts = [[recognize_matrix_expression(j).doit() for j in i] for i in parts]

    def _get_shape(elem):
        if isinstance(elem, MatrixExpr):
            return elem.shape
        return (1, 1)

    def get_rank(parts):
        return sum([j not in (1, None) for i in parts for j in _get_shape(i)])

    ranks = [get_rank(i) for i in parts]
    rank = ranks[0]

    def contract_one_dims(parts):
        if len(parts) == 1:
            return parts[0]
        else:
            p1, p2 = parts[:2]
            if p2.is_Matrix:
                p2 = p2.T
            pbase = p1*p2
            if len(parts) == 2:
                return pbase
            else:  # len(parts) > 2
                if pbase.is_Matrix:
                    raise ValueError("")
                return pbase*Mul.fromiter(parts[2:])

    if rank <= 2:
        return Add.fromiter([contract_one_dims(i) for i in parts])

    return Derivative(expr, x)
コード例 #9
0
ファイル: matadd.py プロジェクト: sylee957/sympy
    def __new__(cls, *args, evaluate=False, check=False, _sympify=True):
        if not args:
            return cls.identity

        # This must be removed aggressively in the constructor to avoid
        # TypeErrors from GenericZeroMatrix().shape
        args = list(filter(lambda i: cls.identity != i, args))
        if _sympify:
            args = list(map(sympify, args))

        obj = Basic.__new__(cls, *args)

        if check:
            if not any(isinstance(i, MatrixExpr) for i in args):
                return Add.fromiter(args)
            validate(*args)

        if evaluate:
            if not any(isinstance(i, MatrixExpr) for i in args):
                return Add(*args, evaluate=True)
            obj = canonicalize(obj)

        return obj
コード例 #10
0
 def recurse_expr(expr, index_ranges={}):
     if expr.is_Mul:
         nonmatargs = []
         pos_arg = []
         pos_ind = []
         dlinks = {}
         link_ind = []
         counter = 0
         args_ind = []
         for arg in expr.args:
             retvals = recurse_expr(arg, index_ranges)
             assert isinstance(retvals, list)
             if isinstance(retvals, list):
                 for i in retvals:
                     args_ind.append(i)
             else:
                 args_ind.append(retvals)
         for arg_symbol, arg_indices in args_ind:
             if arg_indices is None:
                 nonmatargs.append(arg_symbol)
                 continue
             if isinstance(arg_symbol, MatrixElement):
                 arg_symbol = arg_symbol.args[0]
             pos_arg.append(arg_symbol)
             pos_ind.append(arg_indices)
             link_ind.append([None]*len(arg_indices))
             for i, ind in enumerate(arg_indices):
                 if ind in dlinks:
                     other_i = dlinks[ind]
                     link_ind[counter][i] = other_i
                     link_ind[other_i[0]][other_i[1]] = (counter, i)
                 dlinks[ind] = (counter, i)
             counter += 1
         counter2 = 0
         lines = {}
         while counter2 < len(link_ind):
             for i, e in enumerate(link_ind):
                 if None in e:
                     line_start_index = (i, e.index(None))
                     break
             cur_ind_pos = line_start_index
             cur_line = []
             index1 = pos_ind[cur_ind_pos[0]][cur_ind_pos[1]]
             while True:
                 d, r = cur_ind_pos
                 if pos_arg[d] != 1:
                     if r % 2 == 1:
                         cur_line.append(transpose(pos_arg[d]))
                     else:
                         cur_line.append(pos_arg[d])
                 next_ind_pos = link_ind[d][1-r]
                 counter2 += 1
                 # Mark as visited, there will be no `None` anymore:
                 link_ind[d] = (-1, -1)
                 if next_ind_pos is None:
                     index2 = pos_ind[d][1-r]
                     lines[(index1, index2)] = cur_line
                     break
                 cur_ind_pos = next_ind_pos
         ret_indices = list(j for i in lines for j in i)
         lines = {k: MatMul.fromiter(v) if len(v) != 1 else v[0] for k, v in lines.items()}
         return [(Mul.fromiter(nonmatargs), None)] + [
             (MatrixElement(a, i, j), (i, j)) for (i, j), a in lines.items()
         ]
     elif expr.is_Add:
         res = [recurse_expr(i) for i in expr.args]
         d = collections.defaultdict(list)
         for res_addend in res:
             scalar = 1
             for elem, indices in res_addend:
                 if indices is None:
                     scalar = elem
                     continue
                 indices = tuple(sorted(indices, key=default_sort_key))
                 d[indices].append(scalar*remove_matelement(elem, *indices))
                 scalar = 1
         return [(MatrixElement(Add.fromiter(v), *k), k) for k, v in d.items()]
     elif isinstance(expr, KroneckerDelta):
         i1, i2 = expr.args
         if dimensions is not None:
             identity = Identity(dimensions[0])
         else:
             identity = S.One
         return [(MatrixElement(identity, i1, i2), (i1, i2))]
     elif isinstance(expr, MatrixElement):
         matrix_symbol, i1, i2 = expr.args
         if i1 in index_ranges:
             r1, r2 = index_ranges[i1]
             if r1 != 0 or matrix_symbol.shape[0] != r2+1:
                 raise ValueError("index range mismatch: {0} vs. (0, {1})".format(
                     (r1, r2), matrix_symbol.shape[0]))
         if i2 in index_ranges:
             r1, r2 = index_ranges[i2]
             if r1 != 0 or matrix_symbol.shape[1] != r2+1:
                 raise ValueError("index range mismatch: {0} vs. (0, {1})".format(
                     (r1, r2), matrix_symbol.shape[1]))
         if (i1 == i2) and (i1 in index_ranges):
             return [(trace(matrix_symbol), None)]
         return [(MatrixElement(matrix_symbol, i1, i2), (i1, i2))]
     elif isinstance(expr, Sum):
         return recurse_expr(
             expr.args[0],
             index_ranges={i[0]: i[1:] for i in expr.args[1:]}
         )
     else:
         return [(expr, None)]
コード例 #11
0
ファイル: matexpr.py プロジェクト: asmeurer/sympy
 def recurse_expr(expr, index_ranges={}):
     if expr.is_Mul:
         nonmatargs = []
         pos_arg = []
         pos_ind = []
         dlinks = {}
         link_ind = []
         counter = 0
         args_ind = []
         for arg in expr.args:
             retvals = recurse_expr(arg, index_ranges)
             assert isinstance(retvals, list)
             if isinstance(retvals, list):
                 for i in retvals:
                     args_ind.append(i)
             else:
                 args_ind.append(retvals)
         for arg_symbol, arg_indices in args_ind:
             if arg_indices is None:
                 nonmatargs.append(arg_symbol)
                 continue
             if isinstance(arg_symbol, MatrixElement):
                 arg_symbol = arg_symbol.args[0]
             pos_arg.append(arg_symbol)
             pos_ind.append(arg_indices)
             link_ind.append([None]*len(arg_indices))
             for i, ind in enumerate(arg_indices):
                 if ind in dlinks:
                     other_i = dlinks[ind]
                     link_ind[counter][i] = other_i
                     link_ind[other_i[0]][other_i[1]] = (counter, i)
                 dlinks[ind] = (counter, i)
             counter += 1
         counter2 = 0
         lines = {}
         while counter2 < len(link_ind):
             for i, e in enumerate(link_ind):
                 if None in e:
                     line_start_index = (i, e.index(None))
                     break
             cur_ind_pos = line_start_index
             cur_line = []
             index1 = pos_ind[cur_ind_pos[0]][cur_ind_pos[1]]
             while True:
                 d, r = cur_ind_pos
                 if pos_arg[d] != 1:
                     if r % 2 == 1:
                         cur_line.append(transpose(pos_arg[d]))
                     else:
                         cur_line.append(pos_arg[d])
                 next_ind_pos = link_ind[d][1-r]
                 counter2 += 1
                 # Mark as visited, there will be no `None` anymore:
                 link_ind[d] = (-1, -1)
                 if next_ind_pos is None:
                     index2 = pos_ind[d][1-r]
                     lines[(index1, index2)] = cur_line
                     break
                 cur_ind_pos = next_ind_pos
         ret_indices = list(j for i in lines for j in i)
         lines = {k: MatMul.fromiter(v) if len(v) != 1 else v[0] for k, v in lines.items()}
         return [(Mul.fromiter(nonmatargs), None)] + [
             (MatrixElement(a, i, j), (i, j)) for (i, j), a in lines.items()
         ]
     elif expr.is_Add:
         res = [recurse_expr(i) for i in expr.args]
         d = collections.defaultdict(list)
         for res_addend in res:
             scalar = 1
             for elem, indices in res_addend:
                 if indices is None:
                     scalar = elem
                     continue
                 indices = tuple(sorted(indices, key=default_sort_key))
                 d[indices].append(scalar*remove_matelement(elem, *indices))
                 scalar = 1
         return [(MatrixElement(Add.fromiter(v), *k), k) for k, v in d.items()]
     elif isinstance(expr, KroneckerDelta):
         i1, i2 = expr.args
         if dimensions is not None:
             identity = Identity(dimensions[0])
         else:
             identity = S.One
         return [(MatrixElement(identity, i1, i2), (i1, i2))]
     elif isinstance(expr, MatrixElement):
         matrix_symbol, i1, i2 = expr.args
         if i1 in index_ranges:
             r1, r2 = index_ranges[i1]
             if r1 != 0 or matrix_symbol.shape[0] != r2+1:
                 raise ValueError("index range mismatch: {0} vs. (0, {1})".format(
                     (r1, r2), matrix_symbol.shape[0]))
         if i2 in index_ranges:
             r1, r2 = index_ranges[i2]
             if r1 != 0 or matrix_symbol.shape[1] != r2+1:
                 raise ValueError("index range mismatch: {0} vs. (0, {1})".format(
                     (r1, r2), matrix_symbol.shape[1]))
         if (i1 == i2) and (i1 in index_ranges):
             return [(trace(matrix_symbol), None)]
         return [(MatrixElement(matrix_symbol, i1, i2), (i1, i2))]
     elif isinstance(expr, Sum):
         return recurse_expr(
             expr.args[0],
             index_ranges={i[0]: i[1:] for i in expr.args[1:]}
         )
     else:
         return [(expr, None)]