code: def tf2zpk(b, a):
      r"""Return zero, pole, gain (z, p, k) representation from a numerator,
      denominator representation of a linear filter.
  
      Parameters
      ----------
      b : array_like
          Numerator polynomial coefficients.
      a : array_like
          Denominator polynomial coefficients.
  
      Returns
      -------
      z : ndarray
          Zeros of the transfer function.
      p : ndarray
          Poles of the transfer function.
      k : float
          System gain.
  
      Warning
      -------
      This function may synchronize the device.
  
      See Also
      --------
      scipy.signal.tf2zpk
  
      Notes
      -----
      If some values of `b` are too close to 0, they are removed. In that case,
      a BadCoefficients warning is emitted.
  
      The `b` and `a` arrays are interpreted as coefficients for positive,
      descending powers of the transfer function variable. So the inputs
      :math:`b = [b_0, b_1, ..., b_M]` and :math:`a =[a_0, a_1, ..., a_N]`
      can represent an analog filter of the form:
  
      .. math::
  
          H(s) = \frac
          {b_0 s^M + b_1 s^{(M-1)} + \cdots + b_M}
          {a_0 s^N + a_1 s^{(N-1)} + \cdots + a_N}
  
      or a discrete-time filter of the form:
  
      .. math::
  
          H(z) = \frac
          {b_0 z^M + b_1 z^{(M-1)} + \cdots + b_M}
          {a_0 z^N + a_1 z^{(N-1)} + \cdots + a_N}
  
      This "positive powers" form is found more commonly in controls
      engineering. If `M` and `N` are equal (which is true for all filters
      generated by the bilinear transform), then this happens to be equivalent
      to the "negative powers" discrete-time form preferred in DSP:
  
      .. math::
  
          H(z) = \frac
          {b_0 + b_1 z^{-1} + \cdots + b_M z^{-M}}
          {a_0 + a_1 z^{-1} + \cdots + a_N z^{-N}}
  
      Although this is true for common filters, remember that this is not true
      in the general case. If `M` and `N` are not equal, the discrete-time
      transfer function coefficients must first be converted to the "positive
      powers" form before finding the poles and zeros.
  
      """
      b, a = normalize(b, a)
      b = (b + 0.0) / a[0]
      a = (a + 0.0) / a[0]
      k = b[0].copy()
      b /= b[0]
      z = roots(b)
      p = roots(a)
      return z, p, k
  
imports: import warnings
  import math
  from math import pi, prod
  import cupy
  from cupyx.scipy.special import binom
  import cupyx.scipy.special
  from cupyx.scipy.signal import _optimize
  from cupyx.scipy.signal._polyutils import roots, poly
  from cupyx.scipy.signal._lti_conversion import abcd_normalize
label_desc: Use image node_id 21 for calling a global function with example usage: tf2zpk(b, a) and returns: z,  p,  k