def get_sift_bin_ksize_stride_pad(patch_size, num_spatial_bins):
    """
        Returns a tuple with SIFT parameters, given the patch size and number of spatial bins.
    """

    ksize = 2 * int(patch_size / (num_spatial_bins + 1))
    stride = patch_size // num_spatial_bins
    pad = ksize // 4
    out_size = (patch_size + 2 * pad - (ksize - 1) - 1) // stride + 1

    if out_size != num_spatial_bins:
        raise ValueError(f"Patch size {patch_size} is incompatible with \
            requested number of spatial bins {num_spatial_bins} \
            for SIFT descriptor. Usually it happens when patch size is too small\
            for num_spatial_bins specified")

    return ksize, stride, pad