class_docstr: ARSOptimizer is supposed to maximize an objective function
docstr: reward should be something like
  [reward_pert1_pos, reward_pert1_neg, reward_pert2_pos, reward_pert2_neg, ...]
docstr_tok: ["reward","should","be","something","like","[","reward_pert1_pos",",","reward_pert1_neg",",","reward_pert2_pos",",","reward_pert2_neg",",","...","]"]
code: def update_ars_params(self, rewards: torch.Tensor) -> None:
      """
      reward should be something like
      [reward_pert1_pos, reward_pert1_neg, reward_pert2_pos, reward_pert2_neg, ...]
      """
      assert (
          len(self.perturbations) > 0
      ), "must call sample_perturbed_params before this function"
      assert rewards.shape == (
          2 * self.n_pert,
      ), "rewards must have length 2 * n_pert"
      rank = {}
      rewards = rewards.numpy()
      for pert_idx in range(self.n_pert):
          reward_pos = rewards[2 * pert_idx]
          reward_neg = rewards[2 * pert_idx + 1]
          rank[pert_idx] = max(reward_pos, reward_neg)
          self.perturbations[pert_idx] *= reward_pos - reward_neg
      std_r = np.std(rewards)
      weight_sum = 0
      for pert_idx in list(
          dict(
              sorted(rank.items(), key=itemgetter(1), reverse=True)
          ).keys()
      )[: self.b_top]:
          weight_sum += self.perturbations[pert_idx]
      self.ars_params = self.ars_params + self.alpha * weight_sum / (
          self.b_top * (std_r if std_r > 0 else 1)
      )
      self.perturbations = []
  
imports: from operator import itemgetter
  import numpy
  import torch
label_desc: Use image node_id 2 for calling the ARSOptimizer obj's underlying member method code with example usage: obj.update_ars_params(rewards) without return types