'interpret other and call one of the following
self._mul_scalar()
self._mul_vector()
self._mul_multivector()
self._mul_sparse_matrix()'

def __mul__(self, other):

    (M, N) = self.shape
    if (other.__class__ is np.ndarray):
        if (other.shape == (N,)):
            return self._mul_vector(other)
        elif (other.shape == (N, 1)):
            return self._mul_vector(other.ravel()).reshape(M, 1)
        elif ((other.ndim == 2) and (other.shape[0] == N)):
            return self._mul_multivector(other)
    if isscalarlike(other):
        return self._mul_scalar(other)
    if issparse(other):
        if (self.shape[1] != other.shape[0]):
            raise ValueError('dimension    mismatch')
        return self._mul_sparse_matrix(other)
    other_a = np.asanyarray(other)
    if ((other_a.ndim == 0) and (other_a.dtype == np.object_)):
        return NotImplemented
    try:
        other.shape
    except AttributeError:
        other = other_a
    if ((other.ndim == 1) or ((other.ndim == 2) and (other.shape[1] == 1))):
        if ((other.shape != (N,)) and (other.shape != (N, 1))):
            raise ValueError('dimension    mismatch')
        result = self._mul_vector(np.ravel(other))
        if isinstance(other, np.matrix):
            result = np.asmatrix(result)
        if ((other.ndim == 2) and (other.shape[1] == 1)):
            result = result.reshape((-1), 1)
        return result
    elif (other.ndim == 2):
        if (other.shape[0] != self.shape[1]):
            raise ValueError('dimension    mismatch')
        result = self._mul_multivector(np.asarray(other))
        if isinstance(other, np.matrix):
            result = np.asmatrix(result)
        return result
    else:
        raise ValueError('could    not    interpret    dimensions')
