def diagonal_matrix_tiling(start, stop, bandwidth, edge=0, verbose=False):
    """
    Generate a stream of tiling coordinates that guarantee to cover a diagonal
    area of the matrix of size 'bandwidth'. cis-signal only!

    Parameters
    ----------
    start : int
        Starting position of the matrix slice to be tiled (inclusive, bins,
        0-based).
    stop : int
        End position of the matrix slice to be tiled (exclusive, bins, 0-based).
    edge : int
        Small edge around each tile to be included in the yielded coordinates.
    bandwidth : int
        Diagonal tiling is guaranteed to cover a diagonal are of width
        'bandwidth'.

    Yields
    ------
    Pairs of indices for every chunk use those indices [cstart:cstop) to fetch
    chunks from the cooler-object:
    >>> clr.matrix()[cstart:cstop, cstart:cstop]

    Notes
    -----
    Specify a [start,stop) region of a matrix you want to tile diagonally.
    Each slice is characterized by the coordinate of the top-left corner and
    size.

    * * * * * * * * * * *  0-th slice
    *       *           *
    *       *           *
    *   * * * * *       *  i-th slice
    *   *   *   *       *
    * * * * *   *       *
    *   *       *       *
    *   * * * * *       *
    *                   *
    *              ...  *  ...
    *                   *
    *                   *
    * * * * * * * * * * *

    These slices are supposed to cover up a diagonal band of size 'bandwidth'.

    """
    size = stop - start
    tiles = size // bandwidth + bool(size % bandwidth)
    if verbose:
        print('matrix of size {}X{} to be split so that\n'.format(size,
            size) + """  diagonal region of size {} would be completely
"""
            .format(bandwidth) +
            '  covered by the tiling, additionally keeping\n' +
            """  a small 'edge' of size w={}, to allow for
""".format(edge) +
            '  meaningfull convolution around boundaries.\n' +
            '  Resulting number of tiles is {}'.format(tiles - 1) +
            '  Non-edge case size of each tile is {}X{}'.format(2 * (
            bandwidth + edge), 2 * (bandwidth + edge)))
    for t in range(1, tiles):
        lw = max(0, bandwidth * (t - 1) - edge)
        rw = min(size, bandwidth * (t + 1) + edge)
        yield lw + start, rw + start
