code: def calculate_gains_sieve(dtypes, parallel, fastmath, cache):
      @njit(dtypes, parallel=parallel, fastmath=fastmath, cache=cache)
      def calculate_gains_sieve_(
          X,
          k,
          current_values,
          selections,
          gains,
          total_gains,
          max_values,
          n_selected,
          idxs,
      ):
          n, d = X.shape
          t = max_values.shape[0]
  
          for j in prange(t):
              for i in range(n):
                  if n_selected[j] == k:
                      break
  
                  idx = idxs[i]
                  threshold = (max_values[j] / 2.0 - total_gains[j]) / (
                      k - n_selected[j]
                  )
                  maximum = numpy.maximum(
                      X[i][:d], current_values[j][:d]
                  )
                  gain = maximum.mean() - total_gains[j]
  
                  if gain > threshold:
                      current_values[j][:d] = maximum
                      total_gains[j] = maximum.mean()
  
                      selections[j, n_selected[j]] = idx
                      gains[j, n_selected[j]] = gain
                      n_selected[j] += 1
  
      return calculate_gains_sieve_
  
file_path: apricot/apricot/functions/facilityLocation.py
imports: import numpy
  from .base import BaseGraphSelection
  from ..optimizers import LazyGreedy
  from ..optimizers import ApproximateLazyGreedy
  from ..optimizers import SieveGreedy
  from tqdm import tqdm
  from numba import njit
  from numba import prange
label_desc: Use image node_id 3 for calling a global function with example usage: calculate_gains_sieve(dtypes, parallel, fastmath, cache) and returns: calculate_gains_sieve_