code: def make_gaussian_blobs(
      n_matrices=100,
      n_dim=2,
      class_sep=1.0,
      class_disp=1.0,
      return_centers=False,
      center_dataset=False,
      random_state=None,
      centers=None,
      *,
      n_jobs=1,
      sampling_method="auto",
  ):
      """Generate SPD dataset with two classes sampled from Riemannian Gaussian.
  
      Generate a dataset with SPD matrices drawn from two Riemannian Gaussian
      distributions. The distributions have the same class dispersions and the
      distance between their centers of mass is an input parameter. Useful for
      testing classification or clustering methods.
  
      Parameters
      ----------
      n_matrices : int, default=100
          How many matrices to generate for each class.
      n_dim : int, default=2
          Dimensionality of the SPD matrices generated by the distributions.
      class_sep : float, default=1.0
          Parameter controlling the separability of the classes.
      class_disp : float, default=1.0
          Intra dispersion of the points sampled from each class.
      centers : ndarray, shape (2, n_dim, n_dim), default=None
          List with the centers of mass for each class. If None, the centers are
          sampled randomly based on class_sep.
      return_centers : bool, default=False
          If True, then return the centers of each cluster
      center_dataset : bool, default=False
          If True, re-center the simulated dataset to the Identity. If False,
          the dataset is centered around a random SPD matrix.
      random_state : int, RandomState instance or None, default=None
          Pass an int for reproducible output across multiple function calls.
      n_jobs : int, default=1
          The number of jobs to use for the computation. This works by computing
          each of the class centroid in parallel. If -1 all CPUs are used.
      sampling_method : str, default='auto'
          Name of the sampling method used to sample samples_r. It can be
          'auto', 'slice' or 'rejection'. If it is 'auto', the sampling_method
          will be equal to 'slice' for n_dim != 2 and equal to
          'rejection' for n_dim = 2.
  
          .. versionadded:: 0.4
  
      Returns
      -------
      X : ndarray, shape (2*n_matrices, n_dim, n_dim)
          Set of SPD matrices.
      y : ndarray, shape (2*n_matrices,)
          Labels corresponding to each matrix.
      centers : ndarray, shape (2, n_dim, n_dim)
          The centers of each class. Only returned if ``return_centers=True``.
  
      Notes
      -----
      .. versionadded:: 0.3
  
      """
      if not isinstance(class_sep, float):
          raise ValueError(
              f"class_sep must be a float (Got {class_sep})"
          )
  
      rs = check_random_state(random_state)
      seeds = rs.randint(100, size=2)
  
      if centers is None:
          C0_in = np.eye(n_dim)  # first class mean at Identity at first
          Pv = rs.randn(n_dim, n_dim)  # create random tangent vector
          Pv = (Pv + Pv.T) / 2  # symmetrize
          Pv = Pv / np.linalg.norm(Pv)  # normalize
          P = expm(Pv)  # take it back to the SPD manifold
          C1_in = powm(
              P, alpha=class_sep
          )  # control distance to Identity
  
      else:
          C0_in, C1_in = centers
  
      # sample data points from class 0
      X0 = sample_gaussian_spd(
          n_matrices=n_matrices,
          mean=C0_in,
          sigma=class_disp,
          random_state=seeds[0],
          n_jobs=n_jobs,
          sampling_method=sampling_method,
      )
      y0 = np.zeros(n_matrices)
  
      # sample data points from class 1
      X1 = sample_gaussian_spd(
          n_matrices=n_matrices,
          mean=C1_in,
          sigma=class_disp,
          random_state=seeds[1],
          n_jobs=n_jobs,
          sampling_method=sampling_method,
      )
  
      y1 = np.ones(n_matrices)
  
      # concatenate the samples
      X = np.concatenate([X0, X1])
  
      # re-center the dataset to the Identity
      M = mean_riemann(X)
      M_invsqrt = invsqrtm(M)
      X = M_invsqrt @ X @ M_invsqrt
  
      if not center_dataset:
          # center the dataset to a random SPD matrix
          M = generate_random_spd_matrix(n_dim=n_dim, random_state=rs)
          M_sqrt = sqrtm(M)
          X = M_sqrt @ X @ M_sqrt
  
      # concatenate the labels for each class
      y = np.concatenate([y0, y1]).astype(int)
  
      # randomly permute the samples of the dataset
      idx = rs.permutation(len(X))
      X, y = X[idx], y[idx]
  
      if return_centers:
          if centers is None:
              C0_out = mean_riemann(X[y == 0])
              C1_out = mean_riemann(X[y == 1])
          else:
              C0_out = C0_in
              C1_out = C1_in
          centers = np.stack([C0_out, C1_out])
          return X, y, centers
      else:
          return X, y
  
file_path: pyRiemann/pyriemann/datasets/simulated.py
imports: import numpy
  from sklearn.utils.validation import check_random_state
  from ..utils.mean import mean_riemann
  from ..utils.distance import distance_riemann
  from ..utils.base import invsqrtm, powm, sqrtm, expm
  from .sampling import generate_random_spd_matrix, sample_gaussian_spd
  from ..transfer import encode_domains
  from ..utils import deprecated
label_desc: Use image node_id 4 for calling a global function with example usage: make_gaussian_blobs(n_matrices, n_dim, class_sep, class_disp, return_centers, center_dataset, random_state, centers) and returns: X,  y,  centers, X,  y