code: def _restrict_along_direction(
      value_and_gradients_function, position, direction
  ):
      """Restricts a function in n-dimensions to a given direction.
  
      Suppose f: R^n -> R. Then given a point x0 and a vector p0 in R^n, the
      restriction of the function along that direction is defined by:
  
      ```None
      g(t) = f(x0 + t * p0)
      ```
  
      This function performs this restriction on the given function. In addition, it
      also computes the gradient of the restricted function along the restriction
      direction. This is equivalent to computing `dg/dt` in the definition above.
  
      Args:
        value_and_gradients_function: Callable accepting a single real `Tensor`
          argument of shape `[..., n]` and returning a tuple of a real `Tensor` of
          shape `[...]` and a real `Tensor` of shape `[..., n]`. The multivariate
          function whose restriction is to be computed. The output values of the
          callable are the function value and the gradients at the input argument.
        position: `Tensor` of real dtype and shape consumable by
          `value_and_gradients_function`. Corresponds to `x0` in the definition
          above.
        direction: `Tensor` of the same dtype and shape as `position`. The direction
          along which to restrict the function. Note that the direction need not
          be a unit vector.
  
      Returns:
        restricted_value_and_gradients_func: A callable accepting a tensor of shape
          broadcastable to `[...]` and same dtype as `position` and returning a
          namedtuple of `Tensors`. The input tensor is the parameter along the
          direction labelled `t` above. The return value contains fields:
            x: A real `Tensor` of shape `[...]`. The input value `t` where the line
              function was evaluated, after any necessary broadcasting.
            f: A real `Tensor` of shape `[...]` containing the value of the
              function at the point `position + t * direction`.
            df: A real `Tensor` of shape `[...]` containing the derivative at
              `position + t * direction`.
            full_gradient: A real `Tensor` of shape `[..., n]`, the full gradient
              of the original `value_and_gradients_function`.
      """
  
      def _restricted_func(t):
          pt = position + t[..., tf.newaxis] * direction
          t = _broadcast(t, position)
          objective_value, gradient = value_and_gradients_function(pt)
          return ValueAndGradient(
              x=t,
              f=objective_value,
              df=tf.reduce_sum(gradient * direction, axis=-1),
              full_gradient=gradient,
          )
  
      return _restricted_func
  
file_path: probability/tensorflow_probability/python/optimizer/bfgs_utils.py
imports: import collections
  import numpy
  import tensorflow.compat.v2
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.optimizer.linesearch.hager_zhang import hager_zhang
label_desc: Use image node_id 8 for calling a global function with example usage: _restrict_along_direction(value_and_gradients_function, position, direction) and returns: _restricted_func, ValueAndGradient