parameters: (self, game, solver, sym,
                         num_iterations=10000, num_samples=1,
                         num_eval_samples=int(10e4), approx_eval=False,
                         exact_eval=False, avg_trajectory=False,
                         return_trajectory=False)
docstring: Runs solver on game.
  
      Args:
        game: game with minimal functionality (see games/small.py)
        solver: gradient solver (see utils/updates.py)
        sym: bool, true if the game is symmetric across players
        num_iterations: int, number of incremental updates
        num_samples: int, `minibatch' size for stochastic gradient
        num_eval_samples: int, number of samples to estimate exploitability
          default = # of samples for P[|sample_payoff-true| > C/100] < ~5e-7%
          where C = pt.max() - pt.min();
          P[|pt_grad|_inf <= C/100] > (1-5e-7)^num_actions
        approx_eval: bool, whether to evaluate exploitability during
          descent with stochastic samples
        exact_eval: bool, whether to evaluate exploitability during
          descent with exact expectation (req. full payoff tensor)
        avg_trajectory: bool, whether to evaluate w.r.t. the average distribution
          up to time t instead of the distribution at time t
        return_trajectory: bool, whether to record all parameters (e.g., dist)
          during learning and return them -- see solver code for details
      Returns:
        None -- dict of results stored in `results` attribute upon completion
          (key=name of metric, value=[m_0, ..., m_{last_iter}])
docstring_summary: Runs solver on game.
docstring_tokens: Runs solver on game .
function: def approximate_nash(self, game, solver, sym,
                         num_iterations=10000, num_samples=1,
                         num_eval_samples=int(10e4), approx_eval=False,
                         exact_eval=False, avg_trajectory=False,
                         return_trajectory=False):
      """Runs solver on game.
  
      Args:
        game: game with minimal functionality (see games/small.py)
        solver: gradient solver (see utils/updates.py)
        sym: bool, true if the game is symmetric across players
        num_iterations: int, number of incremental updates
        num_samples: int, `minibatch' size for stochastic gradient
        num_eval_samples: int, number of samples to estimate exploitability
          default = # of samples for P[|sample_payoff-true| > C/100] < ~5e-7%
          where C = pt.max() - pt.min();
          P[|pt_grad|_inf <= C/100] > (1-5e-7)^num_actions
        approx_eval: bool, whether to evaluate exploitability during
          descent with stochastic samples
        exact_eval: bool, whether to evaluate exploitability during
          descent with exact expectation (req. full payoff tensor)
        avg_trajectory: bool, whether to evaluate w.r.t. the average distribution
          up to time t instead of the distribution at time t
        return_trajectory: bool, whether to record all parameters (e.g., dist)
          during learning and return them -- see solver code for details
      Returns:
        None -- dict of results stored in `results` attribute upon completion
          (key=name of metric, value=[m_0, ..., m_{last_iter}])
      """
      num_players = game.num_players()
      num_strats = game.num_strategies()
  
      if sym:
        if len(set(num_strats)) != 1:
          raise ValueError('Each player should have the same number of actions.')
        num_strats = num_strats[0]
  
      params = solver.init_vars(num_strats, num_players)  # dist = params[0]
      if sym:
        dist_avg = np.zeros_like(params[0])
        policies = list(range(num_strats))
        num_ckpts = len(policies)
        form_payoffs_appx = self.construct_payoff_matrices_from_samples_sym
        form_payoffs_exact = self.construct_payoff_matrices_exactly_sym
        exp = sym_exp
        estimate_exploitability = self.estimate_exploitability_sym
      else:
        dist_avg = [np.zeros_like(dist_i) for dist_i in params[0]]
        policies = [list(range(num_strats_i)) for num_strats_i in num_strats]
        num_ckpts = [len(policy_i) for policy_i in policies]
        form_payoffs_appx = self.construct_payoff_matrices_from_samples_nonsym
        form_payoffs_exact = self.construct_payoff_matrices_exactly_nonsym
        exp = nonsym_exp
        estimate_exploitability = self.estimate_exploitability_nonsym
  
      exps_exact = []
      exps_solver_exact = []
      exps_approx = []
      exps_solver_approx = []
      grad_norms = []
  
      if return_trajectory:
        params_traj = []
  
      has_temp = False
      if hasattr(solver, 'temperature') or hasattr(solver, 'p'):
        has_temp = True
        temperatures = []
        if hasattr(solver, 'temperature'):
          temp_attr = 'temperature'
        else:
          temp_attr = 'p'
  
      early_exit = False
  
      start = time.time()
  
      # search for nash (sgd)
      for t in range(num_iterations + 1):
        dist = params[0]
        if return_trajectory:
          params_traj.append(params)
  
        if return_trajectory:
          params_traj.append(params)
  
        if has_temp:
          temperatures.append(getattr(solver, temp_attr))
  
        if num_samples < np.inf:
          payoff_matrices = form_payoffs_appx(game, dist, num_samples,
                                              policies, num_players, num_ckpts)
        else:
          payoff_matrices = form_payoffs_exact(game, dist, num_players)
  
        grads, exp_sto, exp_solver_sto = solver.compute_gradients(params,
                                                                  payoff_matrices)
  
        if sym:
          grads_dist = grads[0]
          grad_norms.append(simplex.grad_norm(dist, grads_dist))
        else:
          grad_norm = 0.
          grads_dist = grads[0]
          for dist_i, grads_i in zip(dist, grads_dist[0]):
            grad_norm += simplex.grad_norm(dist_i, grads_i)**2.
          grad_norm = np.sqrt(grad_norm)
          grad_norms.append(grad_norm)
  
        if solver.has_aux:
          solver.record_aux_errors(grads)
  
        if sym:
          dist_avg += (dist - dist_avg) / float(t + 1)
        else:
          for i, dist_i in enumerate(dist):
            dist_avg[i] += (dist_i - dist_avg[i]) / float(t + 1)
  
        if avg_trajectory:
          dist_eval = dist_avg
        else:
          dist_eval = dist
  
        if approx_eval:
          exps_approx.append(exp_sto)
          exps_solver_approx.append(exp_solver_sto)
        if exact_eval:
          pt = game.payoff_tensor()
          exps_exact.append(exp.unreg_exploitability(dist_eval, pt))
          exps_solver_exact.append(solver.exploitability(dist_eval, pt))
  
        # skip the last update so to avoid computing the matching exploitability
        # and gradient norm information outside the loop
        if t < num_iterations:
          params = solver.update(params, grads, t)
          if misc.isnan(params):
            print('Warning: NaN detected in params post-update. Exiting loop.')
            early_exit = True
            break
  
      end = time.time()
      solve_runtime = end - start
      start = end
  
      # evaluating exploitability (monte-carlo)
      exp_estimated = estimate_exploitability(dist_eval, num_eval_samples,
                                              num_ckpts, num_players,
                                              game, policies)
  
      eval_runtime = time.time() - start
  
      results = {'exps_approx': exps_approx,
                 'exps_solver_approx': exps_solver_approx,
                 'exps_exact': exps_exact,
                 'exps_solver_exact': exps_solver_exact,
                 'exp_estimated': exp_estimated,
                 'grad_norms': grad_norms,
                 'dist': dist,
                 'dist_avg': dist_avg,
                 'solve_runtime': solve_runtime,
                 'eval_runtime': eval_runtime,
                 'early_exit': early_exit}
  
      if solver.has_aux:
        results.update({'aux_errors': solver.aux_errors})
  
      if return_trajectory:
        results.update({'params_trajectory': params_traj})
  
      if has_temp:
        results.update({'temperatures': temperatures})
  
      self.results = results
function_tokens: def approximate_nash ( self , game , solver , sym , num_iterations = 10000 , num_samples = 1 , num_eval_samples = int ( 10e4 ) , approx_eval = False , exact_eval = False , avg_trajectory = False , return_trajectory = False ) : num_players = game . num_players ( ) num_strats = game . num_strategies ( ) if sym : if len ( set ( num_strats ) ) != 1 : raise ValueError ( 'Each player should have the same number of actions.' ) num_strats = num_strats [ 0 ] params = solver . init_vars ( num_strats , num_players ) # dist = params[0] if sym : dist_avg = np . zeros_like ( params [ 0 ] ) policies = list ( range ( num_strats ) ) num_ckpts = len ( policies ) form_payoffs_appx = self . construct_payoff_matrices_from_samples_sym form_payoffs_exact = self . construct_payoff_matrices_exactly_sym exp = sym_exp estimate_exploitability = self . estimate_exploitability_sym else : dist_avg = [ np . zeros_like ( dist_i ) for dist_i in params [ 0 ] ] policies = [ list ( range ( num_strats_i ) ) for num_strats_i in num_strats ] num_ckpts = [ len ( policy_i ) for policy_i in policies ] form_payoffs_appx = self . construct_payoff_matrices_from_samples_nonsym form_payoffs_exact = self . construct_payoff_matrices_exactly_nonsym exp = nonsym_exp estimate_exploitability = self . estimate_exploitability_nonsym exps_exact = [ ] exps_solver_exact = [ ] exps_approx = [ ] exps_solver_approx = [ ] grad_norms = [ ] if return_trajectory : params_traj = [ ] has_temp = False if hasattr ( solver , 'temperature' ) or hasattr ( solver , 'p' ) : has_temp = True temperatures = [ ] if hasattr ( solver , 'temperature' ) : temp_attr = 'temperature' else : temp_attr = 'p' early_exit = False start = time . time ( ) # search for nash (sgd) for t in range ( num_iterations + 1 ) : dist = params [ 0 ] if return_trajectory : params_traj . append ( params ) if return_trajectory : params_traj . append ( params ) if has_temp : temperatures . append ( getattr ( solver , temp_attr ) ) if num_samples < np . inf : payoff_matrices = form_payoffs_appx ( game , dist , num_samples , policies , num_players , num_ckpts ) else : payoff_matrices = form_payoffs_exact ( game , dist , num_players ) grads , exp_sto , exp_solver_sto = solver . compute_gradients ( params , payoff_matrices ) if sym : grads_dist = grads [ 0 ] grad_norms . append ( simplex . grad_norm ( dist , grads_dist ) ) else : grad_norm = 0. grads_dist = grads [ 0 ] for dist_i , grads_i in zip ( dist , grads_dist [ 0 ] ) : grad_norm += simplex . grad_norm ( dist_i , grads_i ) ** 2. grad_norm = np . sqrt ( grad_norm ) grad_norms . append ( grad_norm ) if solver . has_aux : solver . record_aux_errors ( grads ) if sym : dist_avg += ( dist - dist_avg ) / float ( t + 1 ) else : for i , dist_i in enumerate ( dist ) : dist_avg [ i ] += ( dist_i - dist_avg [ i ] ) / float ( t + 1 ) if avg_trajectory : dist_eval = dist_avg else : dist_eval = dist if approx_eval : exps_approx . append ( exp_sto ) exps_solver_approx . append ( exp_solver_sto ) if exact_eval : pt = game . payoff_tensor ( ) exps_exact . append ( exp . unreg_exploitability ( dist_eval , pt ) ) exps_solver_exact . append ( solver . exploitability ( dist_eval , pt ) ) # skip the last update so to avoid computing the matching exploitability # and gradient norm information outside the loop if t < num_iterations : params = solver . update ( params , grads , t ) if misc . isnan ( params ) : print ( 'Warning: NaN detected in params post-update. Exiting loop.' ) early_exit = True break end = time . time ( ) solve_runtime = end - start start = end # evaluating exploitability (monte-carlo) exp_estimated = estimate_exploitability ( dist_eval , num_eval_samples , num_ckpts , num_players , game , policies ) eval_runtime = time . time ( ) - start results = { 'exps_approx' : exps_approx , 'exps_solver_approx' : exps_solver_approx , 'exps_exact' : exps_exact , 'exps_solver_exact' : exps_solver_exact , 'exp_estimated' : exp_estimated , 'grad_norms' : grad_norms , 'dist' : dist , 'dist_avg' : dist_avg , 'solve_runtime' : solve_runtime , 'eval_runtime' : eval_runtime , 'early_exit' : early_exit } if solver . has_aux : results . update ( { 'aux_errors' : solver . aux_errors } ) if return_trajectory : results . update ( { 'params_trajectory' : params_traj } ) if has_temp : results . update ( { 'temperatures' : temperatures } ) self . results = results