code: def compute_local_sensitivity_bounds_gnmax(
      votes, num_teachers, sigma, order
  ):
      """Computes a list of max-LS-at-distance-d for the GNMax mechanism.
  
      A more efficient implementation of Algorithms 4 and 5 working in time
      O(teachers*classes). A naive implementation is O(teachers^2*classes) or worse.
  
      Args:
        votes: A numpy array of votes.
        num_teachers: Total number of voting teachers.
        sigma: Standard deviation of the Guassian noise.
        order: The Renyi order.
  
      Returns:
        A numpy array of local sensitivities at distances d, 0 <= d <= num_teachers.
      """
  
      num_classes = len(votes)  # Called m in the paper.
  
      logq0 = _compute_logq0(sigma, order)
      logq1 = _compute_logq1(sigma, order, num_classes)
      logq = pate.compute_logq_gaussian(votes, sigma)
      plateau = _compute_local_sens_gnmax(
          logq1, sigma, num_classes, order
      )
  
      res = np.full(num_teachers, plateau)
  
      if logq1 <= logq <= logq0:
          return res
  
      # Invariant: votes is sorted in the non-increasing order.
      votes = sorted(votes, reverse=True)
  
      res[0] = _compute_local_sens_gnmax(
          logq, sigma, num_classes, order
      )
      curr_d = 0
  
      go_left = logq > logq0  # Otherwise logq < logq1 and we go right.
  
      # Iterate while the following is true:
      #    1. If we are going left, logq is still larger than logq0 and we may still
      #       increase the gap between votes[0] and votes[1].
      #    2. If we are going right, logq is still smaller than logq1.
      while (go_left and logq > logq0 and votes[1] > 0) or (
          not go_left and logq < logq1
      ):
          curr_d += 1
          if go_left:  # Try decreasing logq.
              votes[0] += 1
              votes[1] -= 1
              idx = 1
              # Restore the invariant. (Can be implemented more efficiently by keeping
              # track of the range of indices equal to votes[1]. Does not seem to matter
              # for the overall running time.)
              while (
                  idx < len(votes) - 1 and votes[idx] < votes[idx + 1]
              ):
                  votes[idx], votes[idx + 1] = (
                      votes[idx + 1],
                      votes[idx],
                  )
                  idx += 1
          else:  # Go right, i.e., try increasing logq.
              votes[0] -= 1
              votes[
                  1
              ] += 1  # The invariant holds since otherwise logq >= logq1.
  
          logq = pate.compute_logq_gaussian(votes, sigma)
          res[curr_d] = _compute_local_sens_gnmax(
              logq, sigma, num_classes, order
          )
  
      return res
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import math
  from absl import app
  import numpy
  import scipy
  import sympy
  import core
label_desc: Use image node_id 10 for calling a global function with example usage: compute_local_sensitivity_bounds_gnmax(votes, num_teachers, sigma, order) and returns: res, res