parameters: (
          scenario, metric, ensemble_size, num_evaluations)
return_statement: return result
docstring: Runs `scipy.optimize.fmin` over the `controller_params` of scenario
      (treating the existing parameter values there as the starting point).  The
      metric is run over ensemble_size fixed random seeds.  The optimizer
      is given a budget of num_evaluations metric evaluations.
  
      Because each metric evaluation runs a full ensemble, the total number of
      simulations is ensemble_size * num_evaluations.
docstring_summary: Runs `scipy.optimize.fmin` over the `controller_params` of scenario
      (treating the existing parameter values there as the starting point).  The
      metric is run over ensemble_size fixed random seeds.  The optimizer
      is given a budget of num_evaluations metric evaluations.
docstring_tokens: Runs scipy . optimize . fmin over the controller_params of scenario ( treating the existing parameter values there as the starting point ) . The metric is run over ensemble_size fixed random seeds . The optimizer is given a budget of num_evaluations metric evaluations .
function: def optimize_controller_params(
          scenario, metric, ensemble_size, num_evaluations):
      """Runs `scipy.optimize.fmin` over the `controller_params` of scenario
      (treating the existing parameter values there as the starting point).  The
      metric is run over ensemble_size fixed random seeds.  The optimizer
      is given a budget of num_evaluations metric evaluations.
  
      Because each metric evaluation runs a full ensemble, the total number of
      simulations is ensemble_size * num_evaluations.
      """
      seeds = list(range(1, 1 + ensemble_size))
      metric_evaluation_count = 0
  
      def function_to_optimize(params):
          nonlocal metric_evaluation_count
          metric_evaluation_count += 1
          print(f"Iteration {metric_evaluation_count}: {len(seeds)} rollouts...")
          new_scenario = scenario
          new_scenario["controller_params"] = list(params)
          metric_value = evaluate_metric_once(new_scenario, metric, seeds)
          print(f"   ...{metric_evaluation_count}: metric is {metric_value}")
          return metric_value
  
      try:
          x0 = np.asfarray(scenario["controller_params"])
      except TypeError:
          x0 = (np.asfarray(scenario["controller_params"]["min"])
                + np.asfarray(scenario["controller_params"]["max"])) / 2
  
      result = fmin(func=function_to_optimize,
                    x0=x0,
                    maxfun=num_evaluations)
      return result
function_tokens: def optimize_controller_params ( scenario , metric , ensemble_size , num_evaluations ) : seeds = list ( range ( 1 , 1 + ensemble_size ) ) metric_evaluation_count = 0 def function_to_optimize ( params ) : nonlocal metric_evaluation_count metric_evaluation_count += 1 print ( f"Iteration {metric_evaluation_count}: {len(seeds)} rollouts..." ) new_scenario = scenario new_scenario [ "controller_params" ] = list ( params ) metric_value = evaluate_metric_once ( new_scenario , metric , seeds ) print ( f"   ...{metric_evaluation_count}: metric is {metric_value}" ) return metric_value try : x0 = np . asfarray ( scenario [ "controller_params" ] ) except TypeError : x0 = ( np . asfarray ( scenario [ "controller_params" ] [ "min" ] ) + np . asfarray ( scenario [ "controller_params" ] [ "max" ] ) ) / 2 result = fmin ( func = function_to_optimize , x0 = x0 , maxfun = num_evaluations ) return result