DSPRelated.com
Forums

Matlab filter coefficients

Started by kerasus October 24, 2007
Hi,
I have a problem in designing a filter. I have a 4th order 
IIR Butterworth bandpass filter whose Second order systems 
are represented by :

  sos = [1 0 -1 1 -1.9837350041630541 0.98388232243107987;
         1 0 -1 1 -1.7068352267865177 0.74814388078659311];

and the gain is:

  gain = 0.10073985362198344 ^ 2;

I'm getting the filter coefficient values with sos2tf() 
function such as:

  [b,a] = sos2tf(sos,gain)

and get the result:

  b =
    0.0101 0 -0.0203 0 0.0101

  a =
    1.0000 -3.6906 5.1179 -3.1634 0.7361

and apply these coefficients to the filter:

  y = filter(b,a,x);

This gives a pretty good working filter application. But 
when I try to assign the filter coefficients by hand like 
below (which are same with the results of sos2tf func.):

  b = [ 0.0101 0 -0.0203 0 0.0101 ]

  a = [ 1.0000 -3.6906 5.1179 -3.1634 0.7361 ]

I get very much different filter result. The filter doesn't 
work in the second case. Do anyone knows the cause of this 
problem?
 
Regards
Mursel

On Oct 24, 5:04 am, "kerasus" <murselak...@gmail.com> wrote:
> Hi, > I have a problem in designing a filter. I have a 4th order > IIR Butterworth bandpass filter whose Second order systems > are represented by : > > sos = [1 0 -1 1 -1.9837350041630541 0.98388232243107987; > 1 0 -1 1 -1.7068352267865177 0.74814388078659311]; > > and the gain is: > > gain = 0.10073985362198344 ^ 2; > > I'm getting the filter coefficient values with sos2tf() > function such as: > > [b,a] = sos2tf(sos,gain) > > and get the result: > > b = > 0.0101 0 -0.0203 0 0.0101 > > a = > 1.0000 -3.6906 5.1179 -3.1634 0.7361 > > and apply these coefficients to the filter: > > y = filter(b,a,x); > > This gives a pretty good working filter application. But > when I try to assign the filter coefficients by hand like > below (which are same with the results of sos2tf func.): > > b = [ 0.0101 0 -0.0203 0 0.0101 ] > > a = [ 1.0000 -3.6906 5.1179 -3.1634 0.7361 ] > > I get very much different filter result. The filter doesn't > work in the second case. Do anyone knows the cause of this > problem? > > Regards > Mursel
When you type them in by hand like that you are omitting significant digits that Matlab doesn't display on the screen by default. Try typing 'format long' and then display b and a to the screen. John
>On Oct 24, 5:04 am, "kerasus" <murselak...@gmail.com> wrote: >> Hi, >> I have a problem in designing a filter. I have a 4th order >> IIR Butterworth bandpass filter whose Second order systems >> are represented by : >> >> sos = [1 0 -1 1 -1.9837350041630541 0.98388232243107987; >> 1 0 -1 1 -1.7068352267865177 0.74814388078659311]; >> >> and the gain is: >> >> gain = 0.10073985362198344 ^ 2; >> >> I'm getting the filter coefficient values with sos2tf() >> function such as: >> >> [b,a] = sos2tf(sos,gain) >> >> and get the result: >> >> b = >> 0.0101 0 -0.0203 0 0.0101 >> >> a = >> 1.0000 -3.6906 5.1179 -3.1634 0.7361 >> >> and apply these coefficients to the filter: >> >> y = filter(b,a,x); >> >> This gives a pretty good working filter application. But >> when I try to assign the filter coefficients by hand like >> below (which are same with the results of sos2tf func.): >> >> b = [ 0.0101 0 -0.0203 0 0.0101 ] >> >> a = [ 1.0000 -3.6906 5.1179 -3.1634 0.7361 ] >> >> I get very much different filter result. The filter doesn't >> work in the second case. Do anyone knows the cause of this >> problem? >> >> Regards >> Mursel > >When you type them in by hand like that you are omitting significant >digits that Matlab doesn't display on the screen by default. Try >typing 'format long' and then display b and a to the screen. > >John > >
Thank you John, you are right. I changed the coefficients with exact ones and it worked. But I wonder something; the difference was: b-d ans = 1.0e-004 * 0.4852 0 0.0296 0 0.4852 how can such a small difference be very significant? Is there a way to round them safely? I'm asking that because I have a memory problem with my microcontroller. If I use the exact coefficients the data size exceeds the memory, and I have no chance to change my microcontroller. Can you offer me something?
kerasus wrote:
>> On Oct 24, 5:04 am, "kerasus" <murselak...@gmail.com> wrote: >>> Hi, >>> I have a problem in designing a filter. I have a 4th order >>> IIR Butterworth bandpass filter whose Second order systems >>> are represented by : >>> >>> sos = [1 0 -1 1 -1.9837350041630541 0.98388232243107987; >>> 1 0 -1 1 -1.7068352267865177 0.74814388078659311]; >>> >>> and the gain is: >>> >>> gain = 0.10073985362198344 ^ 2; >>> >>> I'm getting the filter coefficient values with sos2tf() >>> function such as: >>> >>> [b,a] = sos2tf(sos,gain) >>> >>> and get the result: >>> >>> b = >>> 0.0101 0 -0.0203 0 0.0101 >>> >>> a = >>> 1.0000 -3.6906 5.1179 -3.1634 0.7361 >>> >>> and apply these coefficients to the filter: >>> >>> y = filter(b,a,x); >>> >>> This gives a pretty good working filter application. But >>> when I try to assign the filter coefficients by hand like >>> below (which are same with the results of sos2tf func.): >>> >>> b = [ 0.0101 0 -0.0203 0 0.0101 ] >>> >>> a = [ 1.0000 -3.6906 5.1179 -3.1634 0.7361 ] >>> >>> I get very much different filter result. The filter doesn't >>> work in the second case. Do anyone knows the cause of this >>> problem? >>> >>> Regards >>> Mursel >> When you type them in by hand like that you are omitting significant >> digits that Matlab doesn't display on the screen by default. Try >> typing 'format long' and then display b and a to the screen. >> >> John >> >> > > Thank you John, you are right. I changed the coefficients with exact ones > and it worked. But I wonder something; the difference was: > > b-d > > ans = > > 1.0e-004 * > > 0.4852 0 0.0296 0 0.4852 > > how can such a small difference be very significant? Is there a way to > round them safely? I'm asking that because I have a memory problem with my > microcontroller. If I use the exact coefficients the data size exceeds the > memory, and I have no chance to change my microcontroller. Can you offer > me something?
Small differences can be a big deal in recursive filters. You might try quantizing the second order section coefficients and then filtering in concatenated second order sections, rather than quantizing the fourth order coefficients and running a single fourth order filter. John
John Sampson wrote:
> kerasus wrote: > >>> On Oct 24, 5:04 am, "kerasus" <murselak...@gmail.com> wrote: >>> >>>> Hi, >>>> I have a problem in designing a filter. I have a 4th order >>>> IIR Butterworth bandpass filter whose Second order systems >>>> are represented by : >>>> >>>> sos = [1 0 -1 1 -1.9837350041630541 0.98388232243107987; >>>> 1 0 -1 1 -1.7068352267865177 0.74814388078659311]; >>>> >>>> and the gain is: >>>> >>>> gain = 0.10073985362198344 ^ 2; >>>> >>>> I'm getting the filter coefficient values with sos2tf() >>>> function such as: >>>> >>>> [b,a] = sos2tf(sos,gain) >>>> >>>> and get the result: >>>> >>>> b = >>>> 0.0101 0 -0.0203 0 0.0101 >>>> >>>> a = >>>> 1.0000 -3.6906 5.1179 -3.1634 0.7361 >>>> >>>> and apply these coefficients to the filter: >>>> >>>> y = filter(b,a,x); >>>> >>>> This gives a pretty good working filter application. But >>>> when I try to assign the filter coefficients by hand like >>>> below (which are same with the results of sos2tf func.): >>>> >>>> b = [ 0.0101 0 -0.0203 0 0.0101 ] >>>> >>>> a = [ 1.0000 -3.6906 5.1179 -3.1634 0.7361 ] >>>> >>>> I get very much different filter result. The filter doesn't >>>> work in the second case. Do anyone knows the cause of this >>>> problem? >>>> >>>> Regards >>>> Mursel >>> >>> When you type them in by hand like that you are omitting significant >>> digits that Matlab doesn't display on the screen by default. Try >>> typing 'format long' and then display b and a to the screen. >>> >>> John >>> >>> >> >> Thank you John, you are right. I changed the coefficients with exact ones >> and it worked. But I wonder something; the difference was: >> >> b-d >> >> ans = >> >> 1.0e-004 * >> >> 0.4852 0 0.0296 0 0.4852 >> >> how can such a small difference be very significant? Is there a way to >> round them safely? I'm asking that because I have a memory problem >> with my >> microcontroller. If I use the exact coefficients the data size exceeds >> the >> memory, and I have no chance to change my microcontroller. Can you offer >> me something? > > > Small differences can be a big deal in recursive filters. You might try > quantizing the second order section coefficients and then filtering in > concatenated second order sections, rather than quantizing the fourth > order coefficients and running a single fourth order filter. > > John
As you try to operate your filter farther from the sample frequency you will also become more susceptible to small differences in the coefficients. Depending on the needs of your application, you may be able to filter in stages and use decimation to reduce these effects. You said that using the exact coefficients that the data size exceeds that of your system. I have seen the comment here many times that IIR filters usually require 32 bit precision in a fixed point application. If all else fails, you may consider performing "long hand" calculations in software. By "long hand" I mean the way that you were taught to multiply and add large numbers using pen and paper. I have seen this tactic used to obtain 24 bit precision on 8 bit processors in assembly.
On Oct 24, 7:33 am, "kerasus" <murselak...@gmail.com> wrote:

> how can such a small difference be very significant?
The denominator coefficients of your "sos" filter are: d1 = [1 -1.9837350041630541 0.98388232243107987] and d2 = [1 -1.7068352267865177 0.74814388078659311] In Matlab, roots(d1) = 0.991867502081527 + 0.009010035828557i 0.991867502081527 - 0.009010035828557i and roots(d2) = 0.853417613393259 + 0.140791540714445i 0.853417613393259 - 0.140791540714445i Both are stable. But if a = [ 1.0000 -3.6906 5.1179 -3.1634 0.7361 ], then roots(a) = 1.000000000001536 0.985670546913484 0.852464726542490 + 0.141792607448564i 0.852464726542490 - 0.141792607448564i It's unstable.
> Is there a way to round them safely?
You have to reduce the wordsize in a way that maintains stability as well as approximating your desired response. You may also have to deal with limit cycles. Most DSP books have sections dealing with finite register length effects. Greg