docs: def partition(min_range,max_range,max_sum=None):
      '''
      Function that can be helpful for obtaining the state space of a discrete Markov chain or Markov decision processes. 
      Returns a 2d-array with on the rows all possible partitions of the ranges `min_range[j],...,max_range[j]` for each j. 
      If the argument `max_sum` is specified, the numbers will add up to at most `max_sum`
      
      Parameters
      ----------
      min_range : array or list of ints
          `min_range[j]` gives the minimum value for element `j` in the output array. 
      max_range : array or list of ints
          `max_range[j]` gives the maximum value for element `j` in the output array. 
      max_sum : int
          Optional argument. The maximum sum for each partition in the output array. 
         
      Returns
      -------
      out : array
          2d array with all possible partitions of the ranges `min_range[j],...,max_range[j]` summing up to at most `max_sum`.
          
      Example
      -------
      >>> min_range=np.array([1,2,1])
      >>> max_range=np.array([2,4,3])    
      >>> max_sum = 6    
      >>> partition(min_range,max_range,max_sum)    
      array([[1, 2, 1],
             [1, 2, 2],
             [1, 2, 3],
             [1, 3, 1],
             [1, 3, 2],
             [1, 4, 1],
             [2, 2, 1],
             [2, 2, 2],          
             [2, 3, 1]])
      '''
      max_range = np.asarray(max_range, dtype = int).ravel()
      min_range = np.asarray(min_range, dtype = int).ravel()
      full_range = max_range-min_range
      if any(full_range<0):
          raise ValueError("max_range needs to be larger than min_range")
      if max_sum == None:
          max_sum = np.sum(full_range)
      else:
          max_sum -= np.sum(min_range)
      out = partition_zero(full_range,max_sum)
      out += min_range
      return out