Butterworth filter

Low pass filter

The Butterworth low pass filter is a filter type with a constant transfer function in the passband and stopband. It’s transfer function decreases monotone for an increasing f and its slope is -20*N dB/decade. For f = 0 the transfer function returns 1


Butter

The general transfer function of the low pass Butterworth filter looks like:


Butter

The poles of this transfer function are complex:


Butter


In the literature there is often a form like


Butter


used for the transfer function. That comes from the fact that the poles are always conjugate complex. The poles are lying on the left side of a circle like


Butter


And we always have conjugate complex pairs. Her for instance for N = 4


Butter


these pairs are multiplied together like


Butter


and her we have


Butter


and so


Butter


with


Butter
Butter
Butter


If N is odd we get a little different situation


Butter


One pole is pure real here and we get


Butter


with


Butter
Butter



With this the transfer function in s for a low pass Bessel filter for the order 1 to 4 looks like:


Butter



These parameters are independent on fs and fc. They depend only on the order of the filter.


Implemented in a C# function that would be:



public void CalcButterworth(int order)
{
     int i = 1;
     double[] poly = new double[3];
     double[] poly2 = new double[2];
     poly[0] = 1.0;
 
     if (order % 2 == 0)
     {
         poly[2] = 1.0;
         for (i = 1; i <= order / 2; i++)
         {
              poly[1] = 2.0 * Math.Cos((2 * i - 1) * Math.PI / 2 / order);
              a_s = Poly.Mult(a_s, poly);
         }
     }
     else
     {
         poly2[0] = 1.0;
         poly2[1] = 1.0;
         a_s = Poly.Mult(a_s, poly2);
         poly[2] = 1.0;
         for (i = 2; i <= (order + 1) / 2; i++)
         {
              poly[1] = 2.0 * Math.Cos((i - 1) * Math.PI / order);
              a_s = Poly.Mult(a_s, poly);
         }
     }
}




This function calculates the denominator of the transfer function in the Laplace domain and puts it the array a_s. This transfer function must be transformed into the z domain. There the frequencies get into the game.The transformation is done, the same way I did it in Digital filter design, by a bilinear transformation with


Butter


and

Butter


with fc = cut off frequency of the filter and fs = sampling frequency.


Butter


The function for this transformation is more or less the same as I used it in the Bessel filter.



public void TransformToZPlane()
{
     int i, j;
     double[] tempA = new double[2];
     List<double[]> aa = new List<double[]>();
     for (i = 0; i <= order; i++)
     {
         aa.Add(new double[] { 1, -1 });
     }
     tempA[0] = 1;
     tempA[1] = 1;
     b_z = Poly.Power(tempA, order);
     for (i = 0; i <= order; i++)
     {
         double[] tempEl = aa.ElementAt(i);
         tempEl = Poly.Mult(Poly.Power(tempA, i), Poly.Power(tempEl, order - i));
         tempEl = Poly.Mult(tempEl, a_s[i] * Math.Pow(2.0 / tc, order - i));
         aa.RemoveAt(i);
         aa.Insert(i, tempEl);
     }
     for (i = 0; i <= order; i++)
     {
         a_z[i] = 0;
         for (j = 0; j <= order; j++)
              a_z[i] = a_z[i] + aa.ElementAt(j)[i];
     }
     for (i =0; i < b_z.Length; i++)
     {
         b_z[i] = b_z[i] / a_z[0];
     }
     for (i = order; i >= 0; i--)
     {
         a_z[i] = a_z[i] / a_z[0];
     }
}




This function computes the transfer function in the z plane and puts it into the arrays a_z and b_z. I initialize the parameters like




public int order = 4;
double fs = 10000.0;
double fc = 300.0;




and with these I get the transfer function


Butter


With quite a steep slope :-)




High pass filter



The transformation of the low pass filter into a high pass filter is done by a so called low-pass to high-pass transformation. That just means to replace s by 1/s in the Laplace domain. In the transfer function like


Butter


That is


Butter


or without compound fraction


Butter


In the implementation that means I would have to switch the direction of the elements of my denominator polynomial. But as the Butterworth always has symmetric elements in the denominator I can leave that and need just to add the SN in the enumerator. This can be done in the transformation from Laplace to z domain. The following modification in the function TransformToZPlane() does this



public void TransformToZPlane(bool bHighPass)
{
     int i, j;
     double[] tempA = new double[2];
 
     tempA[0] = 1;
     if (bHighPass)
     {
         tempA[1] = -1;
         b_z = Poly.Power(tempA, order);
         b_z = Poly.Mult(b_z, Math.Pow(2.0 / tc, order));
     }
     else
     {
         tempA[1] = 1;
         b_z = Poly.Power(tempA, order);
     }
     tempA[1] = 1;




With this small modification the filter can work as high pass filter as well and shows a transfer function of


Butter

The demo project consists of one main window. It processes a short sample signal (red curve) and displays the filtered signal (blue curve) the cut off frequency, sampling frequency and signal frequency can be set and in the left upper corner of the graphic is a checkbox where high or low pass behaviour can be selected.


Butter


A online solver in JavaScript, that returns the filter parameters, can be found on Butterworth filter

C# Demo Project Butterworth filter
  • Butterworth.zip