code: def dtw_barycenter_averaging_subgradient(
      X,
      barycenter_size=None,
      init_barycenter=None,
      max_iter=30,
      initial_step_size=0.05,
      final_step_size=0.005,
      tol=1e-5,
      random_state=None,
      weights=None,
      metric_params=None,
      verbose=False,
  ):
      """DTW Barycenter Averaging (DBA) method estimated through subgradient
      descent algorithm.
  
      DBA was originally presented in [1]_.
      This implementation is based on a idea from [2]_ (Stochastic Subgradient
      Mean Algorithm).
  
      Parameters
      ----------
      X : array-like, shape=(n_ts, sz, d)
          Time series dataset.
  
      barycenter_size : int or None (default: None)
          Size of the barycenter to generate. If None, the size of the barycenter
          is that of the data provided at fit
          time or that of the initial barycenter if specified.
  
      init_barycenter : array or None (default: None)
          Initial barycenter to start from for the optimization process.
  
      max_iter : int (default: 30)
          Number of iterations of the Expectation-Maximization optimization
          procedure.
  
      initial_step_size : float (default: 0.05)
          Initial step size for the subgradient descent algorithm.
          Default value is the one suggested in [2]_.
  
      final_step_size : float (default: 0.005)
          Final step size for the subgradient descent algorithm.
          Default value is the one suggested in [2]_.
  
      tol : float (default: 1e-5)
          Tolerance to use for early stopping: if the decrease in cost is lower
          than this value, the
          Expectation-Maximization procedure stops.
  
      random_state : int, RandomState instance or None, optional (default=None)
          If int, random_state is the seed used by the random number generator;
          If RandomState instance, random_state is the random number generator;
          If None, the random number generator is the RandomState instance used
          by `np.random`.
  
      weights: None or array
          Weights of each X[i]. Must be the same size as len(X).
          If None, uniform weights are used.
  
      metric_params: dict or None (default: None)
          DTW constraint parameters to be used.
          See :ref:`tslearn.metrics.dtw_path <fun-tslearn.metrics.dtw_path>` for
          a list of accepted parameters
          If None, no constraint is used for DTW computations.
  
      verbose : boolean (default: False)
          Whether to print information about the cost at each iteration or not.
  
      Returns
      -------
      numpy.array of shape (barycenter_size, d) or (sz, d) if barycenter_size \
              is None
          DBA barycenter of the provided time series dataset.
  
      Examples
      --------
      >>> time_series = [[1, 2, 3, 4], [1, 2, 4, 5]]
      >>> dtw_barycenter_averaging_subgradient(
      ...     time_series,
      ...     max_iter=10,
      ...     random_state=0
      ... )  # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
      array([[1. ],
             [2. ],
             [3.5...],
             [4.5...]])
  
      References
      ----------
      .. [1] F. Petitjean, A. Ketterlin & P. Gancarski. A global averaging method
         for dynamic time warping, with applications to clustering. Pattern
         Recognition, Elsevier, 2011, Vol. 44, Num. 3, pp. 678-693
  
      .. [2] D. Schultz and B. Jain. Nonsmooth Analysis and Subgradient Methods
         for Averaging in Dynamic Time Warping Spaces.
         Pattern Recognition, 74, 340-358.
      """
      rng = check_random_state(random_state)
  
      X_ = to_time_series_dataset(X)
      if barycenter_size is None:
          barycenter_size = X_.shape[1]
      weights = _set_weights(weights, X_.shape[0])
      if init_barycenter is None:
          barycenter = _init_avg(X_, barycenter_size)
      else:
          barycenter_size = init_barycenter.shape[0]
          barycenter = init_barycenter
      cost_prev, cost = numpy.inf, numpy.inf
      eta = initial_step_size
      n = X_.shape[0]
      for it in range(max_iter):
          shuffled_indices = rng.permutation(n)
          for idx in shuffled_indices:
              Xi = X_[idx : idx + 1]
              wi = weights[idx : idx + 1]
              list_p_k, cost = _mm_assignment(
                  Xi, barycenter, weights, metric_params
              )
              list_diag_v_k, list_w_k = _subgradient_valence_warping(
                  list_p_k, barycenter_size, wi
              )
              if verbose:
                  print("[DBA] epoch %d, cost: %.3f" % (it + 1, cost))
              barycenter = _subgradient_update_barycenter(
                  Xi, list_diag_v_k, list_w_k, wi.sum(), barycenter, eta
              )
              if it == 0:
                  eta -= (initial_step_size - final_step_size) / n
          if abs(cost_prev - cost) < tol:
              break
          elif cost_prev < cost:
              warnings.warn(
                  "DBA loss is increasing while it should not be. "
                  "Stopping optimization.",
                  ConvergenceWarning,
              )
              break
          else:
              cost_prev = cost
      return barycenter
  
imports: import numpy
  import warnings
  from scipy.interpolate import interp1d
  from sklearn.exceptions import ConvergenceWarning
  from sklearn.utils import check_random_state
  from ..metrics import dtw_path
  from ..utils import to_time_series_dataset, ts_size
  from .utils import _set_weights
label_desc: Use image node_id 13 for calling a global function with example usage: dtw_barycenter_averaging_subgradient(X, barycenter_size, init_barycenter, max_iter, initial_step_size, final_step_size, tol, random_state, weights, metric_params, verbose) and returns: barycenter