def downscale_shape(shape, scale_factor, ceil_mode=True):
    """ Compute new shape after downscaling a volume by given scale factor.

    Arguments:
        shape [tuple] - input shape
        scale_factor [tuple or int] - scale factor used for down-sampling.
        ceil_mode [bool] - whether to apply ceil to output shape (default: True)
    """
    scale_ = (scale_factor,) * len(shape) if isinstance(scale_factor, int)\
        else scale_factor
    if ceil_mode:
        return tuple(sh // sf + int((sh % sf) != 0)
                     for sh, sf in zip(shape, scale_))
    else:
        return tuple(sh // sf for sh, sf in zip(shape, scale_))