code: def arfilter(x, a):
      """apply an autoregressive filter to a series x
  
      x can be 2d, a can be 1d, 2d, or 3d
  
      Parameters
      ----------
      x : array_like
          data array, 1d or 2d, if 2d then observations in rows
      a : array_like
          autoregressive filter coefficients, ar lag polynomial
          see Notes
  
      Returns
      -------
      y : ndarray, 2d
          filtered array, number of columns determined by x and a
  
      Notes
      -----
  
      In general form this uses the linear filter ::
  
          y = a(L)x
  
      where
      x : nobs, nvars
      a : nlags, nvars, npoly
  
      Depending on the shape and dimension of a this uses different
      Lag polynomial arrays
  
      case 1 : a is 1d or (nlags,1)
          one lag polynomial is applied to all variables (columns of x)
      case 2 : a is 2d, (nlags, nvars)
          each series is independently filtered with its own
          lag polynomial, uses loop over nvar
      case 3 : a is 3d, (nlags, nvars, npoly)
          the ith column of the output array is given by the linear filter
          defined by the 2d array a[:,:,i], i.e. ::
  
              y[:,i] = a(.,.,i)(L) * x
              y[t,i] = sum_p sum_j a(p,j,i)*x(t-p,j)
                       for p = 0,...nlags-1, j = 0,...nvars-1,
                       for all t >= nlags
  
  
      Note: maybe convert to axis=1, Not
  
      TODO: initial conditions
  
      """
      x = np.asarray(x)
      a = np.asarray(a)
      if x.ndim == 1:
          x = x[:, None]
      if x.ndim > 2:
          raise ValueError("x array has to be 1d or 2d")
      nvar = x.shape[1]
      nlags = a.shape[0]
      ntrim = nlags // 2
      # for x is 2d with ncols >1
  
      if a.ndim == 1:
          # case: identical ar filter (lag polynomial)
          return signal.convolve(x, a[:, None], mode="valid")
          # alternative:
          # return signal.lfilter(a,[1],x.astype(float),axis=0)
      elif a.ndim == 2:
          if min(a.shape) == 1:
              # case: identical ar filter (lag polynomial)
              return signal.convolve(x, a, mode="valid")
  
          # case: independent ar
          # (a bit like recserar in gauss, but no x yet)
          result = np.zeros((x.shape[0] - nlags + 1, nvar))
          for i in range(nvar):
              # could also use np.convolve, but easier for swiching to fft
              result[:, i] = signal.convolve(
                  x[:, i], a[:, i], mode="valid"
              )
          return result
  
      elif a.ndim == 3:
          # case: vector autoregressive with lag matrices
          #        #not necessary:
          #        if np.any(a.shape[1:] != nvar):
          #            raise ValueError('if 3d shape of a has to be (nobs,nvar,nvar)')
          yf = signal.convolve(x[:, :, None], a)
          yvalid = yf[ntrim:-ntrim, yf.shape[1] // 2, :]
          return yvalid
  
imports: import numpy
  from numpy.testing import assert_equal
  from scipy import signal, stats
  from statsmodels.tsa.filters.filtertools import fftconvolveinv
label_desc: Use image node_id 1 for calling a global function with example usage: arfilter(x, a) and returns: signal, result, signal, yvalid