title: Convert 2nd order Butterworth to 1st order - Part II -
body: <p>I'm trying to convert my working 2nd-order Butterworth low pass filter to 1st-order in python, but it gives me very big numbers, like flt_y_1st[299]: 26198491071387576370322954146679741443295686950912.0. Here's my 2nd-order and 1st-order Butterworth:</p>
  
  <pre><code>import math
  import numpy as np
  import matplotlib.pyplot as plt
  
  from scipy.signal import lfilter
  from scipy.signal import butter
  
  def butter_lowpass(cutoff, fs, order=1):
      nyq = 0.5 * fs
      normal_cutoff = cutoff / nyq
      b, a = butter(order, normal_cutoff, btype='low', analog=False)
      return b, a
  
  def butter_lowpass_filter(data, cutoff, fs, order=1):
      b, a = butter_lowpass(cutoff, fs, order=order)
      y = lfilter(b, a, data)
      return y
  
  def bw_2nd(y, fc, fs):
      filtered_y = np.zeros(len(y))
  
      omega_c = math.tan(np.pi*fc/fs)
      k1 = np.sqrt(2)*omega_c
      k2 = omega_c**2
      a0 = k2/(1+k1+k2)
      a1 = 2*a0
      a2 = a0
      k3 = 2*a0/k2
      b1 = -(-2*a0+k3)
      b2 = -(1-2*a0-k3)
  
      filtered_y[0] = y[0]
      filtered_y[1] = y[1]
  
      for i in range(2, len(y)):
          filtered_y[i] = a0*y[i]+a1*y[i-1]+a2*y[i-2]-(b1*filtered_y[i-1]+b2*filtered_y[i-2])
  
      return filtered_y
  
  
  def bw_1st(y, fc, fs):
      filtered_y = np.zeros(len(y))
  
      omega_c = math.tan(np.pi*fc/fs)
      k1 = np.sqrt(2)*omega_c
      k2 = omega_c**2
      a0 = k2/(1+k1+k2)
      a1 = 2*a0
      k3 = 2*a0/k2
      b1 = -(-2*a0+k3)
  #    b1 = -(-2*a0)  # &lt;= Removing k3 makes better, but still not perfect
  
      filtered_y[0] = y[0]
  
      for i in range(1, len(y)):
         filtered_y[i] = a0*y[i]+a1*y[i-1]-(b1*filtered_y[i-1])
  
      return filtered_y
  
  f = 100
  fs = 2000
  x = np.arange(300)
  y = np.sin(2 * np.pi * f * x / fs)
  
  flt_y_2nd = bw_2nd(y, 120, 2000)
  flt_y_scipy = butter_lowpass_filter(y, 120, 2000, 1)
  flt_y_1st = bw_1st(y, 120, 2000)
  
  for i in x:
      print('y[%d]: %6.3f flt_y_2nd[%d]: %6.3f flt_y_scipy[%d]: %6.3f flt_y_1st[%d]: %8.5f' % (i, y[i], i, flt_y_2nd[i], i, flt_y_scipy[i], i, flt_y_1st[i]))
  
  plt.subplot(1, 1, 1)
  plt.xlabel('Time [ms]')
  plt.ylabel('Acceleration [g]')
  lines = plt.plot(x, y, x, flt_y_2nd, x, flt_y_scipy, x, flt_y_1st)
  l1, l2, l3, l4 = lines
  plt.setp(l1, linewidth=1, color='g', linestyle='-')
  plt.setp(l2, linewidth=1, color='b', linestyle='-')
  plt.setp(l3, linewidth=1, color='y', linestyle='-')
  plt.setp(l4, linewidth=1, color='r', linestyle='-')
  plt.legend(["y", "flt_y_2nd", "flt_y_scipy", "flt_y_1st"])
  plt.grid(True)
  plt.xlim(0, 150)
  plt.ylim(-1.5, 1.5)
  plt.title('flt_y_2nd vs. flt_y_scipy vs. flt_y_1st')
  plt.show()
  </code></pre>
  
  <p>... I removed all [i-2]s, which were a feed-forward and a feed-back. </p>
  
  <p><a href="https://i.stack.imgur.com/nVHUs.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/nVHUs.png" alt="b1 = -(-2*a0+k3)"></a></p>
  
  <p>However, it seems that's not enough. I think I need to change some equations in a0, b1, etc.  For example, when I remove '+k3' from b1, I get a plot like this (looks better, doesn't it?):</p>
  
  <p><a href="https://i.stack.imgur.com/EcxJh.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/EcxJh.png" alt="b1 = -(-2*a0)"></a></p>
  
  <p>I'm not specialized in filters, but at least I know that this 1st order differs from that of scipy.butter. So, please help me find correct coefficients. Thank you in advance.</p>
  
  <p>Here's my reference: <a href="http://biomech.byu.edu/portals/83/docs/exsc663/part01/filtering_considerations.pdf" rel="nofollow noreferrer">filtering_considerations.pdf</a></p>