(self, other)
Return self*other where other is either a scalar or a matrix
        of compatible dimensions.

        Examples
        ========

        >>> from sympy.matrices import Matrix
        >>> A = Matrix([[1, 2, 3], [4, 5, 6]])
        >>> 2*A == A*2 == Matrix([[2, 4, 6], [8, 10, 12]])
        True
        >>> B = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
        >>> A*B
        Matrix([
        [30, 36, 42],
        [66, 81, 96]])
        >>> B*A
        Traceback (most recent call last):
        ...
        ShapeError: Matrices size mismatch.
        >>>

        See Also
        ========

        matrix_multiply_elementwise
Return self*other where other is either a scalar or a matrix
        of compatible dimensions.
Return self * other where other is either a scalar or a matrix of compatible dimensions .
def __mul__(self, other):
        """Return self*other where other is either a scalar or a matrix
        of compatible dimensions.

        Examples
        ========

        >>> from sympy.matrices import Matrix
        >>> A = Matrix([[1, 2, 3], [4, 5, 6]])
        >>> 2*A == A*2 == Matrix([[2, 4, 6], [8, 10, 12]])
        True
        >>> B = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
        >>> A*B
        Matrix([
        [30, 36, 42],
        [66, 81, 96]])
        >>> B*A
        Traceback (most recent call last):
        ...
        ShapeError: Matrices size mismatch.
        >>>

        See Also
        ========

        matrix_multiply_elementwise
        """
        if getattr(other, 'is_Matrix', False):
            # The following implmentation is equivalent, but about 5% slower
            #ma, na = A.shape
            #mb, nb = B.shape
            #
            #if na != mb:
            #    raise ShapeError()
            #product = Matrix(ma, nb, lambda i, j: 0)
            #for i in range(ma):
            #    for j in range(nb):
            #        s = 0
            #        for k in range(na):
            #            s += A[i, k]*B[k, j]
            #        product[i, j] = s
            #return product
            A = self
            B = other
            if A.cols != B.rows:
                raise ShapeError("Matrices size mismatch.")
            if A.cols == 0:
                return classof(A, B)._new(A.rows, B.cols, lambda i, j: 0)
            blst = B.T.tolist()
            alst = A.tolist()
            return classof(A, B)._new(A.rows, B.cols, lambda i, j:
                reduce(lambda k, l: k + l,
                    [a_ik * b_kj for a_ik, b_kj in zip(alst[i], blst[j])]))
        else:
            return self._new(self.rows, self.cols,
                [i*other for i in self._mat])
def __mul__ ( self , other ) : if getattr ( other , 'is_Matrix' , False ) : # The following implmentation is equivalent, but about 5% slower #ma, na = A.shape #mb, nb = B.shape # #if na != mb: #    raise ShapeError() #product = Matrix(ma, nb, lambda i, j: 0) #for i in range(ma): #    for j in range(nb): #        s = 0 #        for k in range(na): #            s += A[i, k]*B[k, j] #        product[i, j] = s #return product A = self B = other if A . cols != B . rows : raise ShapeError ( "Matrices size mismatch." ) if A . cols == 0 : return classof ( A , B ) . _new ( A . rows , B . cols , lambda i , j : 0 ) blst = B . T . tolist ( ) alst = A . tolist ( ) return classof ( A , B ) . _new ( A . rows , B . cols , lambda i , j : reduce ( lambda k , l : k + l , [ a_ik * b_kj for a_ik , b_kj in zip ( alst [ i ] , blst [ j ] ) ] ) ) else : return self . _new ( self . rows , self . cols , [ i * other for i in self . _mat ] )