code: def _bcd(
      G, X, R, active_set, one_ovr_lc, n_orient, alpha_lc, list_G_j_c
  ):
      """Implement one full pass of BCD.
  
      BCD stands for Block Coordinate Descent.
      This function make use of scipy.linalg.get_blas_funcs to speed reasons.
  
      Parameters
      ----------
      G : array, shape (n_sensors, n_active)
          The gain matrix a.k.a. lead field.
      X : array, shape (n_sources, n_times)
          Sources, modified in place.
      R : array, shape (n_sensors, n_times)
          The residuals: R = M - G @ X, modified in place.
      active_set : array of bool, shape (n_sources, )
          Mask of active sources, modified in place.
      one_ovr_lc : array, shape (n_positions, )
          One over the lipschitz constants.
      n_orient : int
          Number of dipoles per positions (typically 1 or 3).
      n_positions : int
          Number of source positions.
      alpha_lc: array, shape (n_positions, )
          alpha * (Lipschitz constants).
      """
      X_j_new = np.zeros_like(X[:n_orient, :], order="C")
      dgemm = _get_dgemm()
  
      for j, G_j_c in enumerate(list_G_j_c):
          idx = slice(j * n_orient, (j + 1) * n_orient)
          G_j = G[:, idx]
          X_j = X[idx]
          dgemm(
              alpha=one_ovr_lc[j],
              beta=0.0,
              a=R.T,
              b=G_j,
              c=X_j_new.T,
              overwrite_c=True,
          )
          # X_j_new = G_j.T @ R
          # Mathurin's trick to avoid checking all the entries
          was_non_zero = X_j[0, 0] != 0
          # was_non_zero = np.any(X_j)
          if was_non_zero:
              dgemm(
                  alpha=1.0,
                  beta=1.0,
                  a=X_j.T,
                  b=G_j_c.T,
                  c=R.T,
                  overwrite_c=True,
              )
              # R += np.dot(G_j, X_j)
              X_j_new += X_j
          block_norm = sqrt(sum_squared(X_j_new))
          if block_norm <= alpha_lc[j]:
              X_j.fill(0.0)
              active_set[idx] = False
          else:
              shrink = max(1.0 - alpha_lc[j] / block_norm, 0.0)
              X_j_new *= shrink
              dgemm(
                  alpha=-1.0,
                  beta=1.0,
                  a=X_j_new.T,
                  b=G_j_c.T,
                  c=R.T,
                  overwrite_c=True,
              )
              # R -= np.dot(G_j, X_j_new)
              X_j[:] = X_j_new
              active_set[idx] = True
  
imports: import functools
  from math import sqrt
  import numpy
  from ..time_frequency._stft import istft, stft, stft_norm1, stft_norm2
  from ..utils import _check_option, _get_blas_funcs, _validate_type, logger, sum_squared, verbose, warn
  from .mxne_debiasing import compute_bias
label_desc: Use image node_id 9 for calling a global function with example usage: _bcd(G, X, R, active_set, one_ovr_lc, n_orient, alpha_lc, list_G_j_c) without return types