code: def _CRsweep(A, B, Findex, Cindex, nu, thetacr, method):
      
      n = A.shape[0]    # problem size
      numax = nu
      z = np.zeros((n,))
      e = deepcopy(B[:, 0])
      e[Cindex] = 0.0
      enorm = norm(e)
      rhok = 1
      it = 0
  
      while True:
          if method == 'habituated':
              gauss_seidel(A, e, z, iterations=1)
              e[Cindex] = 0.0
          elif method == 'concurrent':
              gauss_seidel_indexed(A, e, z, indices=Findex, iterations=1)
          else:
              raise NotImplementedError('method not recognized: need habituated '
                                        'or concurrent')
  
          enorm_old = enorm
          enorm = norm(e)
          rhok_old = rhok
          rhok = enorm / enorm_old
          it += 1
  
          # criteria 1 -- fast convergence
          if rhok < 0.1 * thetacr:
              break
          # criteria 2 -- at least nu iters, small relative change in CF (<0.1)
          elif ((abs(rhok - rhok_old) / rhok) < 0.1) and (it >= nu):
              break
  
      return rhok, e
docs: Perform CR sweeps on a target vector.
  
      Internal function called by CR. Performs habituated or concurrent
      relaxation sweeps on target vector. Stops when either (i) very fast
      convergence, CF < 0.1*thetacr, are observed, or at least a given number
      of sweeps have been performed and the relative change in CF < 0.1.
  
      Parameters
      ----------
      A : csr_matrix
      B : array like
          Target near null space mode
      Findex : array like
          List of F indices in current splitting
      Cindex : array like
          List of C indices in current splitting
      nu : int
          minimum number of relaxation sweeps to do
      thetacr
          Desired convergence factor
  
      Returns
      -------
      rho : float
          Convergence factor of last iteration
      e : array like
          Smoothed error vector