class_docstr: Adaptive gradient descent.
class_docstr_tok: ["Adaptive","gradient","descent","."]
docstr: Perform adaptive gradient descent.
  
  Frechet mean of (weighted) points using adaptive time-steps
  The loss function optimized is :math:`||M_1(x)||_x`
  (where :math:`M_1(x)` is the tangent mean at x) rather than
  the mean-square-distance (MSD) because this simplifies computations.
  Adaptivity is done in a Levenberg-Marquardt style weighting variable tau
  between the first order and the second order Gauss-Newton gradient descent.
  
  Parameters
  ----------
  points : array-like, shape=[n_samples, *metric.shape]
      Points to be averaged.
  weights : array-like, shape=[n_samples,], optional
      Weights associated to the points.
  
  Returns
  -------
  current_mean: array-like, shape=[*metric.shape]
      Weighted Frechet mean of the points.
code: def minimize(self, space, points, weights=None):
      """Perform adaptive gradient descent.
  
      Frechet mean of (weighted) points using adaptive time-steps
      The loss function optimized is :math:`||M_1(x)||_x`
      (where :math:`M_1(x)` is the tangent mean at x) rather than
      the mean-square-distance (MSD) because this simplifies computations.
      Adaptivity is done in a Levenberg-Marquardt style weighting variable tau
      between the first order and the second order Gauss-Newton gradient descent.
  
      Parameters
      ----------
      points : array-like, shape=[n_samples, *metric.shape]
          Points to be averaged.
      weights : array-like, shape=[n_samples,], optional
          Weights associated to the points.
  
      Returns
      -------
      current_mean: array-like, shape=[*metric.shape]
          Weighted Frechet mean of the points.
      """
      n_points = gs.shape(points)[0]
  
      tau_max = 1e6
      tau_mul_up = 1.6511111
      tau_min = 1e-6
      tau_mul_down = 0.1
  
      if n_points == 1:
          return points[0]
  
      current_mean = (
          points[0] if self.init_point is None else self.init_point
      )
  
      if weights is None:
          weights = gs.ones((n_points,))
      sum_weights = gs.sum(weights)
  
      tau = self.init_step_size
      iteration = 0
  
      logs = space.metric.log(point=points, base_point=current_mean)
      var = (
          gs.sum(
              space.metric.squared_norm(logs, current_mean) * weights
          )
          / sum_weights
      )
  
      current_tangent_mean = _scalarmulsum(weights, logs)
      current_tangent_mean /= sum_weights
      sq_norm_current_tangent_mean = space.metric.squared_norm(
          current_tangent_mean, base_point=current_mean
      )
  
      while (
          sq_norm_current_tangent_mean > self.epsilon**2
          and iteration < self.max_iter
      ):
          iteration += 1
  
          shooting_vector = tau * current_tangent_mean
          next_mean = space.metric.exp(
              tangent_vec=shooting_vector, base_point=current_mean
          )
  
          logs = space.metric.log(point=points, base_point=next_mean)
          var = (
              gs.sum(
                  space.metric.squared_norm(logs, current_mean)
                  * weights
              )
              / sum_weights
          )
  
          next_tangent_mean = _scalarmulsum(weights, logs)
          next_tangent_mean /= sum_weights
          sq_norm_next_tangent_mean = space.metric.squared_norm(
              next_tangent_mean, base_point=next_mean
          )
  
          if sq_norm_next_tangent_mean < sq_norm_current_tangent_mean:
              current_mean = next_mean
              current_tangent_mean = next_tangent_mean
              sq_norm_current_tangent_mean = sq_norm_next_tangent_mean
              tau = min(tau_max, tau_mul_up * tau)
          else:
              tau = max(tau_min, tau_mul_down * tau)
  
      if iteration == self.max_iter:
          logging.warning(
              "Maximum number of iterations %d reached. The mean may be inaccurate",
              self.max_iter,
          )
  
      if self.verbose:
          logging.info(
              "n_iter: %d, final variance: %e, final dist: %e, final_step_size: %e",
              iteration,
              var,
              sq_norm_current_tangent_mean,
              tau,
          )
  
      return current_mean
  
imports: import abc
  import logging
  import math
  from sklearn.base import BaseEstimator
  import geomstats.backend
  import geomstats.errors
  from geomstats.geometry.discrete_curves import ElasticTranslationMetric, SRVTranslationMetric
  from geomstats.geometry.euclidean import EuclideanMetric
  from geomstats.geometry.hypersphere import HypersphereMetric
  from geomstats.geometry.matrices import MatricesMetric
  from geomstats.geometry.minkowski import MinkowskiMetric
label_desc: Use image node_id 1 for calling the AdaptiveGradientDescent obj's underlying member method code with example usage: obj.minimize(space, points, weights) and returns: current_mean, points