def test_classof():
    A = Matrix(3, 3, range(9))
    B = ImmutableMatrix(3, 3, range(9))
    C = MatrixSymbol('C', 3, 3)
    assert classof(A, A) == Matrix
    assert classof(B, B) == ImmutableMatrix
    assert classof(A, B) == ImmutableMatrix
    assert classof(B, A) == ImmutableMatrix
    raises(TypeError, lambda: classof(A, C))
Exemple #2
0
def test_classof():
    A = Matrix(3, 3, range(9))
    B = ImmutableMatrix(3, 3, range(9))
    C = MatrixSymbol('C', 3, 3)
    assert classof(A, A) == Matrix
    assert classof(B, B) == ImmutableMatrix
    assert classof(A, B) == ImmutableMatrix
    assert classof(B, A) == ImmutableMatrix
    raises(TypeError, lambda: classof(A, C))
Exemple #3
0
    def _eval_matrix_mul(self, other):
        other_len = other.rows * other.cols
        new_len = self.rows * other.cols
        new_mat = [self.zero] * new_len

        # if we multiply an n x 0 with a 0 x m, the
        # expected behavior is to produce an n x m matrix of zeros
        if self.cols != 0 and other.rows != 0:
            self_cols = self.cols
            mat = self._mat
            other_mat = other._mat
            for i in range(new_len):
                row, col = i // other.cols, i % other.cols
                row_indices = range(self_cols * row, self_cols * (row + 1))
                col_indices = range(col, other_len, other.cols)
                vec = [
                    mat[a] * other_mat[b]
                    for a, b in zip(row_indices, col_indices)
                ]
                try:
                    new_mat[i] = Add(*vec)
                except (TypeError, SympifyError):
                    # Some matrices don't work with `sum` or `Add`
                    # They don't work with `sum` because `sum` tries to add `0`
                    # Fall back to a safe way to multiply if the `Add` fails.
                    new_mat[i] = reduce(lambda a, b: a + b, vec)

        return classof(self, other)._new(self.rows,
                                         other.cols,
                                         new_mat,
                                         copy=False)
Exemple #4
0
    def _eval_matrix_mul(self, other):
        from sympy import Add
        # cache attributes for faster access
        self_rows, self_cols = self.rows, self.cols
        other_rows, other_cols = other.rows, other.cols
        other_len = other_rows * other_cols
        new_mat_rows = self.rows
        new_mat_cols = other.cols

        # preallocate the array
        new_mat = [self.zero]*new_mat_rows*new_mat_cols

        # if we multiply an n x 0 with a 0 x m, the
        # expected behavior is to produce an n x m matrix of zeros
        if self.cols != 0 and other.rows != 0:
            # cache self._mat and other._mat for performance
            mat = self._mat
            other_mat = other._mat
            for i in range(len(new_mat)):
                row, col = i // new_mat_cols, i % new_mat_cols
                row_indices = range(self_cols*row, self_cols*(row+1))
                col_indices = range(col, other_len, other_cols)
                vec = (mat[a]*other_mat[b] for a,b in zip(row_indices, col_indices))
                try:
                    new_mat[i] = Add(*vec)
                except (TypeError, SympifyError):
                    # Block matrices don't work with `sum` or `Add` (ISSUE #11599)
                    # They don't work with `sum` because `sum` tries to add `0`
                    # initially, and for a matrix, that is a mix of a scalar and
                    # a matrix, which raises a TypeError. Fall back to a
                    # block-matrix-safe way to multiply if the `sum` fails.
                    vec = (mat[a]*other_mat[b] for a,b in zip(row_indices, col_indices))
                    new_mat[i] = reduce(lambda a,b: a + b, vec)
        return classof(self, other)._new(new_mat_rows, new_mat_cols, new_mat, copy=False)
Exemple #5
0
    def _eval_matrix_mul(self, other):
        from sympy import Add
        # cache attributes for faster access
        self_rows, self_cols = self.rows, self.cols
        other_rows, other_cols = other.rows, other.cols
        other_len = other_rows * other_cols
        new_mat_rows = self.rows
        new_mat_cols = other.cols

        # preallocate the array
        new_mat = [S.Zero]*new_mat_rows*new_mat_cols

        # if we multiply an n x 0 with a 0 x m, the
        # expected behavior is to produce an n x m matrix of zeros
        if self.cols != 0 and other.rows != 0:
            # cache self._mat and other._mat for performance
            mat = self._mat
            other_mat = other._mat
            for i in range(len(new_mat)):
                row, col = i // new_mat_cols, i % new_mat_cols
                row_indices = range(self_cols*row, self_cols*(row+1))
                col_indices = range(col, other_len, other_cols)
                vec = (mat[a]*other_mat[b] for a,b in zip(row_indices, col_indices))
                try:
                    new_mat[i] = Add(*vec)
                except (TypeError, SympifyError):
                    # Block matrices don't work with `sum` or `Add` (ISSUE #11599)
                    # They don't work with `sum` because `sum` tries to add `0`
                    # initially, and for a matrix, that is a mix of a scalar and
                    # a matrix, which raises a TypeError. Fall back to a
                    # block-matrix-safe way to multiply if the `sum` fails.
                    vec = (mat[a]*other_mat[b] for a,b in zip(row_indices, col_indices))
                    new_mat[i] = reduce(lambda a,b: a + b, vec)
        return classof(self, other)._new(new_mat_rows, new_mat_cols, new_mat, copy=False)
Exemple #6
0
def matrix_multiply_elementwise(A, B):
    """Return the Hadamard product (elementwise product) of A and B

    >>> from sympy.matrices import matrix_multiply_elementwise
    >>> from sympy.matrices import Matrix
    >>> A = Matrix([[0, 1, 2], [3, 4, 5]])
    >>> B = Matrix([[1, 10, 100], [100, 10, 1]])
    >>> matrix_multiply_elementwise(A, B)
    Matrix([
    [  0, 10, 200],
    [300, 40,   5]])

    See Also
    ========

    __mul__
    """
    if A.shape != B.shape:
        raise ShapeError()
    shape = A.shape
    return classof(A, B)._new(shape[0], shape[1],
                              lambda i, j: A[i, j] * B[i, j])
Exemple #7
0
def matrix_multiply_elementwise(A, B):
    """Return the Hadamard product (elementwise product) of A and B

    >>> from sympy.matrices import matrix_multiply_elementwise
    >>> from sympy.matrices import Matrix
    >>> A = Matrix([[0, 1, 2], [3, 4, 5]])
    >>> B = Matrix([[1, 10, 100], [100, 10, 1]])
    >>> matrix_multiply_elementwise(A, B)
    Matrix([
    [  0, 10, 200],
    [300, 40,   5]])

    See Also
    ========

    __mul__
    """
    if A.shape != B.shape:
        raise ShapeError()
    shape = A.shape
    return classof(A, B)._new(shape[0], shape[1],
                              lambda i, j: A[i, j]*B[i, j])
Exemple #8
0
 def _eval_matrix_mul_elementwise(self, other):
     mat = [a * b for a, b in zip(self._mat, other._mat)]
     return classof(self, other)._new(self.rows, self.cols, mat, copy=False)
Exemple #9
0
 def _eval_add(self, other):
     # we assume both arguments are dense matrices since
     # sparse matrices have a higher priority
     mat = [a + b for a, b in zip(self._mat, other._mat)]
     return classof(self, other)._new(self.rows, self.cols, mat, copy=False)
Exemple #10
0
 def _eval_matrix_mul_elementwise(self, other):
     mat = [a*b for a,b in zip(self._mat, other._mat)]
     return classof(self, other)._new(self.rows, self.cols, mat, copy=False)
Exemple #11
0
 def _eval_add(self, other):
     # we assume both arguments are dense matrices since
     # sparse matrices have a higher priority
     mat = [a + b for a,b in zip(self._mat, other._mat)]
     return classof(self, other)._new(self.rows, self.cols, mat, copy=False)