code: def median_euclid(
      X, *, tol=10e-6, maxiter=50, init=None, weights=None
  ):
      r"""Euclidean geometric median of matrices.
  
      The Euclidean geometric median minimizes the sum of Euclidean distances
      :math:`d_E` to all matrices [1]_ [2]_:
  
      .. math::
          \arg \min_{\mathbf{M}} \sum_i w_i \ d_E (\mathbf{M}, \mathbf{X}_i)
  
      Geometric median is different from the marginal median provided by NumPy
      [3]_.
  
      Parameters
      ----------
      X : ndarray, shape (n_matrices, n, m)
          Set of matrices.
      tol : float, default=10e-6
          The tolerance to stop the iterative algorithm.
      maxiter : int, default=50
          The maximum number of iterations.
      init : None | ndarray, shape (n, m), default=None
          A matrix used to initialize the iterative algorithm.
          If None, the weighted Euclidean mean is used.
      weights : None | ndarray, shape (n_matrices,), default=None
          Weights for each matrix. If None, it uses equal weights.
  
      Returns
      -------
      M : ndarray, shape (n, m)
          Euclidean geometric median.
  
      Notes
      -----
      .. versionadded:: 0.4
  
      References
      ----------
      .. [1] `Sur le point pour lequel la somme des distances de n points donnés
          est minimum
          <https://www.jstage.jst.go.jp/article/tmj1911/43/0/43_0_355/_pdf>`_
          E Weiszfeld. Tohoku Mathematical Journal, 1937, 43, pp. 355-386.
      .. [2] `The multivariate L1-median and associated data depth
          <https://www.pnas.org/doi/pdf/10.1073/pnas.97.4.1423>`_
          Y Vardi and C-H Zhan. Proceedings of the National Academy of Sciences,
          2000, vol. 97, no 4, p. 1423-1426
      .. [3] https://numpy.org/doc/stable/reference/generated/numpy.median.html
      """
      n_matrices, _, _ = X.shape
      weights = check_weights(weights, n_matrices)
      if init is None:
          M = mean_euclid(X, sample_weight=weights)
      else:
          M = init
  
      for _ in range(maxiter):
          dists = distance(X, M, metric="euclid")[:, 0]
          is_zero = dists == 0
  
          w = weights[~is_zero] / dists[~is_zero]
          Mnew = mean_euclid(
              X[~is_zero], sample_weight=w
          )  # Eq(2.4) of [2]
  
          n_zeros = np.sum(is_zero)
          if n_zeros > 0:
              R = np.einsum("a,abc->bc", w, X[~is_zero] - M)  # Eq(2.7)
              r = np.linalg.norm(R, ord="fro")
              rinv = 0 if r == 0 else np.mean(weights[is_zero]) / r
              Mnew = (
                  max(0, 1 - rinv) * Mnew + min(1, rinv) * M
              )  # Eq(2.6)
  
          crit = np.linalg.norm(Mnew - M, ord="fro")
          M = Mnew
          if crit <= tol:
              break
      else:
          warnings.warn("Convergence not reached")
  
      return M
  
file_path: pyRiemann/pyriemann/utils/median.py
imports: import warnings
  import numpy
  from .base import sqrtm, invsqrtm, logm, expm
  from .distance import distance
  from .mean import mean_euclid
  from .utils import check_weights
label_desc: Use image node_id 1 for calling a global function with example usage: median_euclid(X) and returns: M