class_docstr: Class to solve the initial value problem (IVP) for exp.
class_docstr_tok: ["Class","to","solve","the","initial","value","problem","(","IVP",")","for","exp","."]
docstr: Compute the next point on the geodesic.
  
  Parameters
  ----------
  current_point : array-like, shape=[n_vertices, 3]
      Current point on the geodesic.
  next_point : array-like, shape=[n_vertices, 3]
      Next point on the geodesic.
  
  Returns
  -------
  next_next_point : array-like, shape=[n_vertices, 3]
      Next next point on the geodesic.
docstr_tok: ["Compute","the","next","point","on","the","geodesic",".","Parameters","--","--","--","--","--","current_point",":","array-like",",","shape=","[","n_vertices",",","3","]","Current","point","on","the","geodesic",".","next_point",":","array-like",",","shape=","[","n_vertices",",","3","]","Next","point","on","the","geodesic",".","Returns","--","--","--","-","next_next_point",":","array-like",",","shape=","[","n_vertices",",","3","]","Next","next","point","on","the","geodesic","."]
code: def _stepforward(self, space, current_point, next_point):
      """Compute the next point on the geodesic.
  
      Parameters
      ----------
      current_point : array-like, shape=[n_vertices, 3]
          Current point on the geodesic.
      next_point : array-like, shape=[n_vertices, 3]
          Next point on the geodesic.
  
      Returns
      -------
      next_next_point : array-like, shape=[n_vertices, 3]
          Next next point on the geodesic.
      """
      current_point = gs.array(current_point)
      next_point = gs.array(next_point)
      n_vertices = current_point.shape[-2]
  
      zeros = gs.zeros_like(current_point, dtype=float)
      next_point_clone = gs.copy(next_point)
  
      def energy_objective(next_next_point):
          """Compute the energy objective to minimize.
  
          Parameters
          ----------
          next_next_point : array-like, shape=[n_vertices*3]
              Next next point on the geodesic.
  
          Returns
          -------
          energy_tot : array-like, shape=[,]
              Energy objective to minimize.
          """
          next_next_point = gs.reshape(
              gs.array(next_next_point), (n_vertices, 3)
          )
          current_to_next = next_point - current_point
          next_to_next_next = next_next_point - next_point
  
          def _inner_product_with_current_to_next(tangent_vec):
              """Compute inner-product with tangent vector `current_to_next`.
  
              The tangent vector `current_to_next` is the vector going from the
              current point, i.e. discrete surface, to the next point on the
              geodesic that is being computed.
              """
              return space.metric.inner_product(
                  current_to_next, tangent_vec, current_point
              )
  
          def _inner_product_with_next_to_next_next(tangent_vec):
              """Compute inner-product with tangent vector `next_to_next_next`.
  
              The tangent vector `next_to_next_next` is the vector going from the
              next point, i.e. discrete surface, to the next next point on the
              geodesic that is being computed.
              """
              return space.metric.inner_product(
                  next_to_next_next, tangent_vec, next_point
              )
  
          def _norm(base_point):
              """Compute norm of `next_to_next_next` at the base_point.
  
              The tangent vector `next_to_next_next` is the vector going from the
              next point, i.e. discrete surface, to the next next point on the
              geodesic that is being computed.
              """
              return space.metric.squared_norm(
                  next_to_next_next, base_point
              )
  
          _, energy_1 = gs.autodiff.value_and_grad(
              _inner_product_with_current_to_next
          )(zeros)
          _, energy_2 = gs.autodiff.value_and_grad(
              _inner_product_with_next_to_next_next
          )(zeros)
          _, energy_3 = gs.autodiff.value_and_grad(_norm)(
              next_point_clone
          )
  
          energy_tot = 2 * energy_1 - 2 * energy_2 + energy_3
          return gs.sum(energy_tot**2)
  
      initial_next_next_point = gs.flatten(
          (2 * (next_point - current_point) + current_point)
      )
  
      sol = self.optimizer.minimize(
          energy_objective,
          initial_next_next_point,
      )
  
      return gs.reshape(gs.array(sol.x), (n_vertices, 3))
  
imports: import math
  import geomstats.backend
  from geomstats.geometry.euclidean import Euclidean
  from geomstats.geometry.manifold import Manifold
  from geomstats.geometry.riemannian_metric import RiemannianMetric
  from geomstats.numerics.optimizers import ScipyMinimize
label_desc: Use image node_id 4 for calling the _ExpSolver obj's underlying member method code with example usage: obj._stepforward(space, current_point, next_point) and returns: gs, gs, space, space, space