Provide a 2D block view to 2D array.

    No error checking made. Therefore meaningful (as implemented) only for
    blocks strictly compatible with the shape of A.

def block_view(arr, block=(3, 3)):
    """Provide a 2D block view to 2D array.

    No error checking made. Therefore meaningful (as implemented) only for
    blocks strictly compatible with the shape of A.

    """

    # simple shape and strides computations may seem at first strange
    # unless one is able to recognize the 'tuple additions' involved ;-)
    shape = (arr.shape[0] // block[0], arr.shape[1] // block[1]) + block
    strides = (block[0] * arr.strides[0], block[1] * arr.strides[1]) + arr.strides
    return ast(arr, shape=shape, strides=strides)