import tensorflow as tf

    Returns:

    *sampled_idx_indicator*: boolean tensor of shape [N], True for entries which are sampled.
    """

    negative_idx = tf.logical_not(labels)
    positive_idx = tf.logical_and(labels, indicator)
    negative_idx = tf.logical_and(negative_idx, indicator)

    # Sample positive and negative samples separately
    if sample_size is None:
        max_num_pos = tf.reduce_sum(tf.cast(positive_idx, dtype=tf.int32))
    else:
        max_num_pos = int(positive_fraction * sample_size)
    sampled_pos_idx = subsample_indicator(positive_idx, max_num_pos)
    num_sampled_pos = tf.reduce_sum(tf.cast(sampled_pos_idx, tf.int32))
    if sample_size is None:
        negative_positive_ratio = (1 - positive_fraction) / positive_fraction
        max_num_neg = tf.cast(negative_positive_ratio * tf.cast(num_sampled_pos, dtype=tf.float32),
                              dtype=tf.int32)
    else:
        max_num_neg = sample_size - num_sampled_pos
    sampled_neg_idx = subsample_indicator(negative_idx, max_num_neg)

    return tf.logical_or(sampled_pos_idx, sampled_neg_idx)


def batch_sample_balanced_positive_negative(indicators,
                                            sample_size,
                                            labels,
