Drop values from a sparse matrix encoded as a SciPy coo matrix.

  Args:
    sparse_matrix: a SciPy coo sparse matrix.
    rate: if rate > 0 then non-zero elements of the input matrix
      will be droped uniformly at random.
    min_dropout_rate: minimum value for the dropout rate. If None
      FLAGS.min_dropout_rate is used. If dropout_rate is lower than
      min_dropout_rate it will clipped to min_dropout_rate.
    max_dropout_rate: minimum value for the dropout rate. If None
      FLAGS.max_dropout_rate is used. If dropout_rate is greater than
      max_dropout_rate it will clipped to max_dropout_rate.

  Returns:
    A SciPy coo matrix containing those non zero elements that have not been
    dropped out.

def _dropout_sparse_coo_matrix(sparse_matrix, rate,
                               min_dropout_rate, max_dropout_rate):
  """Drop values from a sparse matrix encoded as a SciPy coo matrix.

  Args:
    sparse_matrix: a SciPy coo sparse matrix.
    rate: if rate > 0 then non-zero elements of the input matrix
      will be droped uniformly at random.
    min_dropout_rate: minimum value for the dropout rate. If None
      FLAGS.min_dropout_rate is used. If dropout_rate is lower than
      min_dropout_rate it will clipped to min_dropout_rate.
    max_dropout_rate: minimum value for the dropout rate. If None
      FLAGS.max_dropout_rate is used. If dropout_rate is greater than
      max_dropout_rate it will clipped to max_dropout_rate.

  Returns:
    A SciPy coo matrix containing those non zero elements that have not been
    dropped out.
  """
  if min_dropout_rate is None:
    min_dropout_rate = FLAGS.min_dropout_rate

  if max_dropout_rate is None:
    max_dropout_rate = FLAGS.max_dropout_rate

  if min_dropout_rate > max_dropout_rate:
    raise ValueError("min_dropout_rate (%f) should be less or equal to "
                     "max_dropout_rate (%f)"
                     % (min_dropout_rate, max_dropout_rate))

  max_frac = 1.0 - min_dropout_rate
  min_frac = 1.0 - max_dropout_rate
  sampling_rate = 1.0 - rate

  sampled_fraction = min(max(sampling_rate, min_frac), max_frac)
  if sampled_fraction != sampling_rate:
    logging.warning("Minimum sampling rate is %2f.", min_frac)
    logging.warning("Maximum sampling rate is %2f.", max_frac)
    logging.warning("Desired sampling rate is %2f.", sampling_rate)
    logging.warning("Desired sampling rate %2f clipped to %2f.", sampling_rate,
                    sampled_fraction)

  num_sampled = min(
      max(int(sparse_matrix.nnz * sampled_fraction), 1), sparse_matrix.nnz)
  sampled_indices = np.random.choice(sparse_matrix.nnz, size=num_sampled,
                                     replace=False)

  return sparse.coo_matrix((sparse_matrix.data[sampled_indices],
                            (sparse_matrix.row[sampled_indices],
                             sparse_matrix.col[sampled_indices])),
                           shape=sparse_matrix.shape)