<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>c# butterworth Archives - CenterSpace</title>
	<atom:link href="https://www.centerspace.net/tag/c-butterworth/feed" rel="self" type="application/rss+xml" />
	<link>https://www.centerspace.net/tag/c-butterworth</link>
	<description>.NET numerical class libraries</description>
	<lastBuildDate>Tue, 01 Mar 2016 21:50:48 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.1.1</generator>
<site xmlns="com-wordpress:feed-additions:1">104092929</site>	<item>
		<title>Butterworth Filters in C#</title>
		<link>https://www.centerspace.net/butterworth-filter-csharp</link>
					<comments>https://www.centerspace.net/butterworth-filter-csharp#comments</comments>
		
		<dc:creator><![CDATA[Paul Shirkey]]></dc:creator>
		<pubDate>Wed, 30 Oct 2013 18:30:45 +0000</pubDate>
				<category><![CDATA[NMath]]></category>
		<category><![CDATA[butterworth filter]]></category>
		<category><![CDATA[c# butterworth]]></category>
		<category><![CDATA[c# butterworth filter]]></category>
		<category><![CDATA[c# data filtering]]></category>
		<category><![CDATA[c# filter]]></category>
		<category><![CDATA[c# iir filtering]]></category>
		<category><![CDATA[nmath filtering]]></category>
		<category><![CDATA[vb.net butterworth]]></category>
		<category><![CDATA[vb.net butterworth filter]]></category>
		<category><![CDATA[vb.net data filtering]]></category>
		<category><![CDATA[vb.net filter]]></category>
		<category><![CDATA[vb.net iir filtering]]></category>
		<guid isPermaLink="false">http://www.centerspace.net/blog/?p=4921</guid>

					<description><![CDATA[<p><img class="excerpt" title="ButterworthFilterExample" src="https://www.centerspace.net/blog/wp-content/uploads/2013/10/ScreenClip7.png" alt="Butterworth Filter Example" /><br />
There are three classes of widely used IIR (recursive) filters in signal processing: Butterworth, Chebyshev, and elliptical. In this article I will discuss the Butterworth filter and provide example code implementing and using the filter. The Chebyshev and elliptical filters will be discussed in follow up articles.   Butterworth filters are desirable for their ease of implementation, good phase response, and their smooth monotonic frequency response in both the pass-band and the stop-band.</p>
<p>The post <a rel="nofollow" href="https://www.centerspace.net/butterworth-filter-csharp">Butterworth Filters in C#</a> appeared first on <a rel="nofollow" href="https://www.centerspace.net">CenterSpace</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>There are three classes of widely used IIR (recursive) filters in signal processing: Butterworth, Chebyshev, and elliptical. In this article I will discuss the Butterworth filter and provide example code implementing and using the filter. The Chebyshev and elliptical filters will be discussed in follow up articles. </p>
<p>Butterworth filters are desirable for their ease of implementation, good phase response, and their smooth monotonic frequency response in both the pass-band and the stop-band. However they don&#8217;t achieve the steep roll-off of Chebyshev filters, but Chebyshev filters achieve this steeper roll-off by allowing either some ripple in the pass-band (type 1) or the stop-band (type 2). The type 2 Chebyshev filters are rarely used so only type 1 Chebyshev filters will be discussed in follow up articles. The elliptical filters strike a balance between the type 1 and type 2 Chebyshev filters by allowing ripple in both the stop and pass-bands while achieving the steepest roll-off gain of all three filter types.  Wikipedia has excellent overview articles discussing the <a href="https://en.wikipedia.org/wiki/Butterworth_filter">Butterworth</a>, the <a href="https://en.wikipedia.org/wiki/Chebyshev_filter">Chebyshev,</a> and the <a href="https://en.wikipedia.org/wiki/Elliptic_filter">elliptical </a>filters, so I&#8217;ll refer you to those articles for a thorough background treatment of each filter type instead of repeating that information here.</p>
<h2> Butterworth Filters </h2>
<p>Butterworth filters exhibited a ripple free frequency response with a <code>-20*n</code> Db/decade roll-off at the cutoff frequency, where <code>n</code> is the order of the filter.  There are only three design parameters for a Butterworth filter, the order <code>n</code>, the cut-off frequency <img decoding="async" src="https://www.centerspace.net/blog/wp-content/uploads/2013/10/CodeCogsEqn7.gif" alt="Cutoff frequency" width="14" height="17" class="alignnone size-full wp-image-5022" />, and the DC gain, <img decoding="async" loading="lazy" src="https://www.centerspace.net/blog/wp-content/uploads/2013/10/CodeCogsEqn6.gif" alt="DC gain" width="20" height="17" class="alignnone size-full wp-image-4971" />, or the gain at zero frequency.  So the gain of any Butterworth filter can be written in terms of these three parameters.<br />
<center><br />
<figure id="attachment_4926" aria-describedby="caption-attachment-4926" style="width: 300px" class="wp-caption alignnone"><a href="https://www.centerspace.net/blog/wp-content/uploads/2013/10/CodeCogsEqn2.gif"><img decoding="async" loading="lazy" src="https://www.centerspace.net/blog/wp-content/uploads/2013/10/CodeCogsEqn2.gif" alt="Butterworth filter gain" width="165" height="47" class="size-full wp-image-4926" /></a><figcaption id="caption-attachment-4926" class="wp-caption-text">Butterworth filter gain</figcaption></figure><br />
</center></p>
<p>Engineers typically think in terms of Hertz, so we can relate the linear frequency cutoff we are accustom to, to the angular frequency we have above, with the familiar equation, <img decoding="async" loading="lazy" src="https://www.centerspace.net/blog/wp-content/uploads/2013/10/CodeCogsEqn41.gif" alt="Angular cut-off frequency" width="76" height="17" class="alignnone size-full wp-image-4941" />.  Now rewriting the above equation in terms of frequency we have:</p>
<p><center><br />
<figure id="attachment_5014" aria-describedby="caption-attachment-5014" style="width: 300px" class="wp-caption alignnone"><a href="https://www.centerspace.net/blog/wp-content/uploads/2013/10/CodeCogsEqn61.gif"><img decoding="async" loading="lazy" src="https://www.centerspace.net/blog/wp-content/uploads/2013/10/CodeCogsEqn61.gif" alt="Butterworth filter gain in terms of f" width="162" height="51" class="size-full wp-image-5014" /></a><figcaption id="caption-attachment-5014" class="wp-caption-text">Butterworth filter gain in terms of f</figcaption></figure></center></p>
<h2> The Butterworth Filter in C#</h2>
<p>To digitally implement a Butterworth filter in code, we work in the frequency domain (for performance reasons), following the three steps outlined in the pseudo code below.</p>
<pre lang="c">
function ButterworthFilter
{
  fftSignal = FFT( signal );

  // Scale FFT by butterworth gain
  for( int w = 0; w < N/2; w++)
    filteredSignal[w] = fftSignal[w] * butterworthGain[w];
  
  return inverseFFT( filteredSignal );
}
</pre>
<p>Given the dual relationship between convolution and multiplication in the time and frequency domains, we could equally well implement this filter by convolving in the time domain the inverse fourier of the Butterworth's frequency response with the signal, but this would require <code>O(n*n)</code> time.  By using the FFT, and working in the frequency domain, we achieve the same effect in <code>O(n* log(n))</code> time, where <code>n</code> is the length of the signal to be filtered. </p>
<pre lang="csharp">
DoubleComplexVector ButterworthFilter( DoubleComplexVector signal, 
   double sampleFrequency, int order, double f0, double DCGain )
    {

      var N = signal.Length;

      // Apply forward FFT
      var fft = new DoubleComplexForward1DFFT( N );
      var signalFFT = fft.FFT( signal );

      if ( f0 > 0 )
      {

        var numBins = N / 2;  // Half the length of the FFT by symmetry
        var binWidth = sampleFrequency / N; // Hz

        // Filter
        System.Threading.Tasks.Parallel.For( 1, N / 2, i =>
        {
          var binFreq = binWidth * i;
          var gain = DCGain / ( Math.Sqrt( ( 1 + 
                        Math.Pow( binFreq / f0, 2.0 * order ) ) ) );
          signalFFT[i] *= gain;
          signalFFT[N - i] *= gain;
        } );

      }

      // Reverse filtered signal
      var ifft = new DoubleComplexBackward1DFFT( N );
      ifft.SetScaleFactorByLength(); // Needed to get the correct amplitude
      signal = ifft.FFT( signalFFT );

      return signal;
   }
</pre>
<p>This general Butterworth filtering code begs a bit of explanation. The FFT provides the Fourier transform for <code>N/2</code> positive frequencies, and symmetrically (via a complex conjugation) for <code>N/2</code> negative frequencies. Because of this we can loop just <code>N/2</code> times scaling the symmetric halves simultaneously by our Butterworth <code>gain</code> in our <code>Parallel.For</code> loop for improved performance. When scaling the FFT by the <code>gain</code> of the Butterworth filter, we must know the angular frequency of each bin we scale, which is captured by the <code>binFreq</code> variable; recalling that the frequency resolution of a length <code>N</code> FFT is <code>( Fs / N / 2 )</code> Hz, where <code>Fs</code> is the sampling frequency. </p>
<p>Although this code will execute very efficiently it can be significantly optimized if it is specialized to filtering only signals of a fixed length and fixed sampling frequency - a very common situation in many systems. In this case the Butterworth gains can all be computed ahead, avoiding the expensive <code>Math.Sqrt()</code> calls, also the NMath FFT classes would only need to be created once outside the filtering routine.  Finally we could do all of the computation in-place and eliminate the copy to a new result vector, with:	 </p>
<pre lang="csharp">
   ...
   // Apply forward FFT in place
   var fft = new DoubleComplexForward1DFFT( N );
   fft.FFTInPlace( signal );
   ...
</pre>
<h2> Filtering Example </h2>
<p>To test our new Butterworth filter, I generated a test signal which is simply the sum of two sinusoids of frequencies 1 Hz and 8 Hz. This continuous signal is then sampled at 25 Hz and filtered with a third order Butterworth filter using a cut-off frequency of 1.5 Hz and a DC gain of one. Finally, a chart is generated of the input signal and of the filtered signal to visualize the action of the filter in the time domain. </p>
<pre lang="csharp">
    public void FilterTest()
    {
      var signal = new DoubleComplexVector( 100 );
      
      var Fs = 25; // Sample rate, 25Hz
      var f1 = 1; // 1 Hz Signal
      var f2 = 8; // 8 Hz Signal
      for ( int t = 0; t < 100; t++ )
      {
        signal[t] = new DoubleComplex( Math.Sin( 2 * Math.PI * f1 / Fs * t ) + 
                    Math.Sin( 2 * Math.PI * f2 / Fs * t ), 0.0 );
      }

      // Filter      
      var filteredSignal = ButterworthFilter( signal, 25, 3, 1.5, 1.0 );

      // Display results
      var chart = NMathChart.ToChart( new DoubleVector( signal.ToRealDataTable() ) );
      chart.Titles[0].Text = "Input signal, sampled at 25 Hz";
      chart.ChartAreas[0].AxisY.Title = "Input signal magnitude";
      var chartfft = NMathChart.ToChart( new DoubleVector( filteredSignal.ToRealDataTable() ) );
      chartfft.Titles[0].Text = "Filtered signal";
      chartfft.ChartAreas[0].AxisY.Title = "Filtered signal magnitude";

      List<Chart> charts = new List<Chart>() { chart, chartfft };
 
      var compositeChart = NMathChart.Compose( charts, 1, 2, NMathChart.AreaLayoutOrder.ColumnMajor );
      compositeChart.Width = 650;
      compositeChart.Height = 300;
      NMathChart.Show( compositeChart );

    }
</pre>
<p>This example code generates the following composite chart showing on the left the unfiltered signal, and on the right the filtered signal.</p>
<figure id="attachment_5057" aria-describedby="caption-attachment-5057" style="width: 660px" class="wp-caption alignnone"><a href="https://www.centerspace.net/blog/wp-content/uploads/2013/10/ScreenClip8.png"><img decoding="async" loading="lazy" src="https://www.centerspace.net/blog/wp-content/uploads/2013/10/ScreenClip8.png" alt="Butterworth filtering example" width="660" height="308" class="size-full wp-image-5057" srcset="https://www.centerspace.net/wp-content/uploads/2013/10/ScreenClip8.png 660w, https://www.centerspace.net/wp-content/uploads/2013/10/ScreenClip8-300x140.png 300w" sizes="(max-width: 660px) 100vw, 660px" /></a><figcaption id="caption-attachment-5057" class="wp-caption-text">Butterworth filtering example</figcaption></figure>
<p>As expected, almost all of the high frequency sinusoid at 8Hz has been eliminated from the original signal.  In this case where the 'noisy' 8 Hz signal is well separated from our 1Hz signal, the Butterworth filter does an excellent job.  The next signal processing blog entry will cover the Chebyshev type 1 filter.</p>
<p>-Happy Computing,</p>
<p>Paul Shirkey</p>
<p>Please contact us at sales@centerspace.net with any questions you may have.</p>
<p>The post <a rel="nofollow" href="https://www.centerspace.net/butterworth-filter-csharp">Butterworth Filters in C#</a> appeared first on <a rel="nofollow" href="https://www.centerspace.net">CenterSpace</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.centerspace.net/butterworth-filter-csharp/feed</wfw:commentRss>
			<slash:comments>13</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4921</post-id>	</item>
	</channel>
</rss>
