docs: def quic(
      S,
      lam,
      mode="default",
      tol=1e-6,
      max_iter=1000,
      Theta0=None,
      Sigma0=None,
      path=None,
      msg=0,
  ):
      """Fits the inverse covariance model according to the given training
      data and parameters.
  
      Parameters
      -----------
      S : 2D ndarray, shape (n_features, n_features)
          Empirical covariance or correlation matrix.
  
      Other parameters described in `class InverseCovariance`.
  
      Returns
      -------
      Theta :
      Sigma :
      opt :
      cputime :
      iters :
      dGap :
      """
      assert mode in ["default", "path", "trace"], "mode = 'default', 'path' or 'trace'."
  
      Sn, Sm = S.shape
      if Sn != Sm:
          raise ValueError("Input data must be square. S shape = {}".format(S.shape))
          return
  
      # Regularization parameter matrix L.
      if isinstance(lam, float):
          _lam = np.empty((Sn, Sm))
          _lam[:] = lam
          _lam[np.diag_indices(Sn)] = 0.  # make sure diagonal is zero
      else:
          assert lam.shape == S.shape, "lam, S shape mismatch."
          _lam = as_float_array(lam, copy=False, force_all_finite=False)
  
      # Defaults.
      optSize = 1
      iterSize = 1
      if mode is "trace":
          optSize = max_iter
  
      # Default Theta0, Sigma0 when both are None.
      if Theta0 is None and Sigma0 is None:
          Theta0 = np.eye(Sn)
          Sigma0 = np.eye(Sn)
  
      assert Theta0 is not None, "Theta0 and Sigma0 must both be None or both specified."
      assert Sigma0 is not None, "Theta0 and Sigma0 must both be None or both specified."
      assert Theta0.shape == S.shape, "Theta0, S shape mismatch."
      assert Sigma0.shape == S.shape, "Theta0, Sigma0 shape mismatch."
      Theta0 = as_float_array(Theta0, copy=False, force_all_finite=False)
      Sigma0 = as_float_array(Sigma0, copy=False, force_all_finite=False)
  
      if mode == "path":
          assert path is not None, "Please specify the path scaling values."
  
          # path must be sorted from largest to smallest and have unique values
          check_path = sorted(set(path), reverse=True)
          assert_array_almost_equal(check_path, path)
  
          path_len = len(path)
          optSize = path_len
          iterSize = path_len
  
          # Note here: memory layout is important:
          # a row of X/W holds a flattened Sn x Sn matrix,
          # one row for every element in _path_.
          Theta = np.empty((path_len, Sn * Sn))
          Theta[0, :] = Theta0.ravel()
          Sigma = np.empty((path_len, Sn * Sn))
          Sigma[0, :] = Sigma0.ravel()
      else:
          path = np.empty(1)
          path_len = len(path)
  
          Theta = np.empty(Theta0.shape)
          Theta[:] = Theta0
          Sigma = np.empty(Sigma0.shape)
          Sigma[:] = Sigma0
  
      # Cython fix for Python3
      # http://cython.readthedocs.io/en/latest/src/tutorial/strings.html
      quic_mode = mode
      if sys.version_info[0] >= 3:
          quic_mode = quic_mode.encode("utf-8")
  
      # Run QUIC.
      opt = np.zeros(optSize)
      cputime = np.zeros(optSize)
      dGap = np.zeros(optSize)
      iters = np.zeros(iterSize, dtype=np.uint32)
      pyquic.quic(
          quic_mode,
          Sn,
          S,
          _lam,
          path_len,
          path,
          tol,
          msg,
          max_iter,
          Theta,
          Sigma,
          opt,
          cputime,
          iters,
          dGap,
      )
  
      if optSize == 1:
          opt = opt[0]
          cputime = cputime[0]
          dGap = dGap[0]
  
      if iterSize == 1:
          iters = iters[0]
  
      # reshape Theta, Sigma in path mode
      Theta_out = Theta
      Sigma_out = Sigma
      if mode == "path":
          Theta_out = []
          Sigma_out = []
          for lidx in range(path_len):
              Theta_out.append(np.reshape(Theta[lidx, :], (Sn, Sn)))
              Sigma_out.append(np.reshape(Sigma[lidx, :], (Sn, Sn)))
  
      return Theta_out, Sigma_out, opt, cputime, iters, dGap