docs: def sample_without_replacement(n, k, num_trials=None, random_state=None):
      """
      Randomly choose k integers without replacement from 0, ..., n-1.
  
      Parameters
      ----------
      n : scalar(int)
          Number of integers, 0, ..., n-1, to sample from.
  
      k : scalar(int)
          Number of integers to sample.
  
      num_trials : scalar(int), optional(default=None)
          Number of trials.
  
      random_state : int or np.random.RandomState, optional
          Random seed (integer) or np.random.RandomState instance to set
          the initial state of the random number generator for
          reproducibility. If None, a randomly initialized RandomState is
          used.
  
      Returns
      -------
      result : ndarray(int, ndim=1 or 2)
          Array of shape (k,) if num_trials is None, or of shape
          (num_trials, k) otherwise, (each row of) which contains k unique
          random elements chosen from 0, ..., n-1.
  
      Examples
      --------
      >>> qe.random.sample_without_replacement(5, 3, random_state=1234)
      array([0, 2, 1])
      >>> qe.random.sample_without_replacement(5, 3, num_trials=4,
      ...                                      random_state=1234)
      array([[0, 2, 1],
             [3, 4, 0],
             [1, 3, 2],
             [4, 1, 3]])
  
      """
      if n <= 0:
          raise ValueError('n must be greater than 0')
      if k > n:
          raise ValueError('k must be smaller than or equal to n')
  
      size = k if num_trials is None else (num_trials, k)
  
      random_state = check_random_state(random_state)
      r = random_state.random_sample(size=size)
      result = _sample_without_replacement(n, r)
  
      return result