def matrix_slice(M, corner_shape, corner='nw'):
    """
    Takes a two dimensional array ``M`` and slices into four parts dictated
    by the ``corner_shape`` and the corner string ``corner``. ::

            m   n
        p [ A | B ]
          [-------]
        q [ C | D ]

    If the given corner and the shape is the whole array then the remaining
    arrays are returned as empty arrays, ``numpy.array([])``.

    Parameters
    ----------
    M : ndarray
        2D input matrix
    corner_shape : tuple
        An integer valued 2-tuple for the shape of the corner
    corner : str
        Defines which corner should be used to start slicing. Possible
        options are the compass abbreviations: ``'nw', 'ne', 'sw', 'se'``.
        The default is the north-west corner.

    Returns
    -------
    A : ndarray
        Upper left corner slice
    B : ndarray
        Upper right corner slice
    C : ndarray
        Lower left corner slice
    D : ndarray
        Lower right corner slice

    Examples
    --------
    >>> A = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
    >>> matrix_slice(A,(1,1))
    (array([[1]]),
     array([[2, 3]]),
     array([[4],
            [7]]),
     array([[5, 6],
            [8, 9]])
    )
    >>> matrix_slice(A, (2,2), 'sw')
    (array([[1, 2]]),
     array([[3]]),
     array([[4, 5],
            [7, 8]]),
     array([[6],
            [9]])
     )
    >>> matrix_slice(A, (0, 0))  % empty A
    (array([], shape=(0, 0), dtype=int32),
     array([], shape=(0, 3), dtype=int32),
     array([], shape=(3, 0), dtype=int32),
     array([[1, 2, 3],
            [4, 5, 6],
            [7, 8, 9]]))
    """
    if corner not in ('ne', 'nw', 'se', 'sw'):
        raise ValueError('The corner string needs to be one of'
                         '"ne, nw, se, sw".')

    x, y = M.shape
    z, w = corner_shape
    if corner == 'nw':
        p, m = z, w
    elif corner == 'ne':
        p, m = x, y - w
    elif corner == 'sw':
        p, m = x - z, w
    else:
        p, m = x - z, y - w

    return M[:p, :m], M[:p, m:], M[p:, :m], M[p:, m:]