(iterate_collection, iteration_idx, objective_fn, update_fn,
                     get_params_fn, first_order, clip_grad_norm)
return [
      update_fn(i=iteration_idx, grad=dv, state=s)
      for (s, dv) in zip(iterate_collection, grads)
  ]
Returns the next iterate in the optimization of objective_fn wrt variables.

  Args:
    iterate_collection: A (potentially structured) container of tf.Tensors
      corresponding to the state of the current iterate.
    iteration_idx: An int Tensor; the iteration number.
    objective_fn: Callable that takes in variables and produces the value of the
      objective function.
    update_fn: Callable that takes in the gradient of the objective function and
      the current iterate and produces the next iterate.
    get_params_fn: Callable that takes in the gradient of the objective function
      and the current iterate and produces the next iterate.
    first_order: If True, prevent the computation of higher order gradients.
    clip_grad_norm: If not None, gradient dimensions are independently clipped
      to lie in the interval [-clip_grad_norm, clip_grad_norm].
Returns the next iterate in the optimization of objective_fn wrt variables.
Returns the next iterate in the optimization of objective_fn wrt variables .
def optimizer_update(iterate_collection, iteration_idx, objective_fn, update_fn,
                     get_params_fn, first_order, clip_grad_norm):
  """Returns the next iterate in the optimization of objective_fn wrt variables.

  Args:
    iterate_collection: A (potentially structured) container of tf.Tensors
      corresponding to the state of the current iterate.
    iteration_idx: An int Tensor; the iteration number.
    objective_fn: Callable that takes in variables and produces the value of the
      objective function.
    update_fn: Callable that takes in the gradient of the objective function and
      the current iterate and produces the next iterate.
    get_params_fn: Callable that takes in the gradient of the objective function
      and the current iterate and produces the next iterate.
    first_order: If True, prevent the computation of higher order gradients.
    clip_grad_norm: If not None, gradient dimensions are independently clipped
      to lie in the interval [-clip_grad_norm, clip_grad_norm].
  """
  variables = [get_params_fn(iterate) for iterate in iterate_collection]

  if tf.executing_eagerly():
    with tf.GradientTape(persistent=True) as g:
      g.watch(variables)
      loss = objective_fn(variables, iteration_idx)
    grads = g.gradient(loss, variables)
  else:
    loss = objective_fn(variables, iteration_idx)
    grads = tf.gradients(ys=loss, xs=variables)

  if clip_grad_norm:
    grads = [
        tf.clip_by_value(grad, -1 * clip_grad_norm, clip_grad_norm)
        for grad in grads
    ]

  if first_order:
    grads = [tf.stop_gradient(dv) for dv in grads]

  return [
      update_fn(i=iteration_idx, grad=dv, state=s)
      for (s, dv) in zip(iterate_collection, grads)
  ]
def optimizer_update ( iterate_collection , iteration_idx , objective_fn , update_fn , get_params_fn , first_order , clip_grad_norm ) : variables = [ get_params_fn ( iterate ) for iterate in iterate_collection ] if tf . executing_eagerly ( ) : with tf . GradientTape ( persistent = True ) as g : g . watch ( variables ) loss = objective_fn ( variables , iteration_idx ) grads = g . gradient ( loss , variables ) else : loss = objective_fn ( variables , iteration_idx ) grads = tf . gradients ( ys = loss , xs = variables ) if clip_grad_norm : grads = [ tf . clip_by_value ( grad , - 1 * clip_grad_norm , clip_grad_norm ) for grad in grads ] if first_order : grads = [ tf . stop_gradient ( dv ) for dv in grads ] return [ update_fn ( i = iteration_idx , grad = dv , state = s ) for ( s , dv ) in zip ( iterate_collection , grads ) ]