Iterate through the blocks that cover an array.

    This function first iterates trough the blocks that recover
    the part of the array given by max_blk_coverage
    and then iterates with smaller blocks for the rest
    of the array.

    :param blk: the N-dimensional shape of the block
    :param shape: the N-dimensional shape of the array
    :return: a generator that yields the blocks

    Example:

        >>> result = list(blk_nd(blk=(5,3), shape=(11, 11)))
        >>> result[0]
        (slice(0, 5, None), slice(0, 3, None))
        >>> result[1]
        (slice(0, 5, None), slice(3, 6, None))
        >>> result[-1]
        (slice(10, 11, None), slice(9, 11, None))

    The generator yields blocks of size blk until
    it covers the part of the array given by
    :func:`max_blk_coverage` and then yields
    smaller blocks until it covers the full array.

    .. seealso::

        :py:func:`blk_nd_short`
          Yields blocks of fixed size

def blk_nd(blk, shape):
    """Iterate through the blocks that cover an array.

    This function first iterates trough the blocks that recover
    the part of the array given by max_blk_coverage
    and then iterates with smaller blocks for the rest
    of the array.

    :param blk: the N-dimensional shape of the block
    :param shape: the N-dimensional shape of the array
    :return: a generator that yields the blocks

    Example:

        >>> result = list(blk_nd(blk=(5,3), shape=(11, 11)))
        >>> result[0]
        (slice(0, 5, None), slice(0, 3, None))
        >>> result[1]
        (slice(0, 5, None), slice(3, 6, None))
        >>> result[-1]
        (slice(10, 11, None), slice(9, 11, None))

    The generator yields blocks of size blk until
    it covers the part of the array given by
    :func:`max_blk_coverage` and then yields
    smaller blocks until it covers the full array.

    .. seealso::

        :py:func:`blk_nd_short`
          Yields blocks of fixed size

    """
    internals = (blk_1d(b, s) for b, s in zip(blk, shape))
    return product(*internals)