class_docstr: Gradient descent algorithm.
class_docstr_tok: ["Gradient","descent","algorithm","."]
docstr: Apply a gradient descent until max_iter or a given tolerance is reached.
docstr_tok: ["Apply","a","gradient","descent","until","max_iter","or","a","given","tolerance","is","reached","."]
code: def minimize(self, x_ini, i_pt, e_pt, grad, exp):
      """Apply a gradient descent until max_iter or a given tolerance is reached."""
      x = x_ini
      for _ in range(self.max_iter):
          grad_x = grad(x, i_pt, e_pt)
          grad_norm = gs.linalg.norm(grad_x)
          if grad_norm < self.tol:
              break
          grad_x = -self.lrate * grad_x
          x = exp(grad_x, x)
      return x
  
imports: from joblib import Parallel, delayed
  import geomstats.backend
  from geomstats.geometry.base import Manifold
  from geomstats.geometry.riemannian_metric import RiemannianMetric
  from geomstats.vectorization import check_is_batch
label_desc: Use image node_id 2 for calling the GradientDescent obj's underlying member method code with example usage: obj.minimize(x_ini, i_pt, e_pt, grad, exp) and returns: x