code: def itakura_parallelogram(
      n_timestamps_1, n_timestamps_2=None, max_slope=2.0
  ):
      """Compute the Itakura parallelogram.
  
      Parameters
      ----------
      n_timestamps_1 : int
          The size of the first time series.
  
      n_timestamps_2 : int (optional, default None)
          The size of the second time series. If None, set to `n_timestamps_1`.
  
      max_slope : float (default = 2.)
          Maximum slope for the parallelogram. Must be >= 1.
  
      Returns
      -------
      region : array, shape = (2, n_timestamps_1)
          Constraint region. The first row consists of the starting indices
          (included) and the second row consists of the ending indices (excluded)
          of the valid rows for each column.
  
      References
      ----------
      .. [1] F. Itakura, "Minimum prediction residual principle applied to
             speech recognition". IEEE Transactions on Acoustics,
             Speech, and Signal Processing, 23(1), 67–72 (1975).
  
      Examples
      --------
      >>> from pyts.metrics import itakura_parallelogram
      >>> print(itakura_parallelogram(5))
      [[0 1 1 2 4]
       [1 3 4 4 5]]
  
      """
      if n_timestamps_2 is None:
          n_timestamps_2 = n_timestamps_1
      min_slope_, max_slope_ = _get_itakura_slopes(
          n_timestamps_1, n_timestamps_2, max_slope
      )
  
      # Now we create the piecewise linear functions defining the parallelogram
      # lower_bound[0] = min_slope * x
      # lower_bound[1] = max_slope * (x - n_timestamps_1) + n_timestamps_2
  
      centered_scale = np.arange(n_timestamps_1) - n_timestamps_1 + 1
      lower_bound = np.empty((2, n_timestamps_1))
      lower_bound[0] = min_slope_ * np.arange(n_timestamps_1)
      lower_bound[1] = max_slope_ * centered_scale + n_timestamps_2 - 1
  
      # take the max of the lower linear funcs
      lower_bound = np.round(lower_bound, 2)
      lower_bound = np.ceil(np.max(lower_bound, axis=0))
  
      # upper_bound[0] = max_slope * x
      # upper_bound[1] = min_slope * (x - n_timestamps_1) + n_timestamps_2
  
      upper_bound = np.empty((2, n_timestamps_1))
      upper_bound[0] = max_slope_ * np.arange(n_timestamps_1) + 1
      upper_bound[1] = min_slope_ * centered_scale + n_timestamps_2
  
      # take the min of the upper linear funcs
      upper_bound = np.round(upper_bound, 2)
      upper_bound = np.floor(np.min(upper_bound, axis=0))
  
      # Little fix for max_slope = 1
      if max_slope == 1:
          if n_timestamps_2 > n_timestamps_1:
              upper_bound[:-1] = lower_bound[1:]
          else:
              upper_bound = lower_bound + 1
  
      region = np.asarray([lower_bound, upper_bound]).astype("int64")
      region = _check_region(region, n_timestamps_1, n_timestamps_2)
      return region
  
imports: import numpy
  from math import ceil, log2, sqrt
  from numba import njit, prange
  from sklearn.utils import check_array
label_desc: Use image node_id 21 for calling a global function with example usage: itakura_parallelogram(n_timestamps_1, n_timestamps_2, max_slope) and returns: region