# Numerically Stable IIR filter

I am making an IIR Filter and I am running into problems with stability with higher orders. The values go off to infinity as soon as it starts.

So far, I've been using MATLAB to generate my filters and then running them in an embedded system. I'm using a band-pass filter, state-space representation and single precision values. If I understand this correctly, the issues happens because the poles are getting too close to the unit circle, so the rounding errors on my coefficients or state space are getting out of hand.

I could reduce the order, but that feels wasteful when I have the computational power to run a higher order filter. Is there a filter design that will improve at a higher order while giving the poles a good margin?

Alternatively, Is there another trick I can use to mitigate this issue?

Given your hardware constrains mentioned in the comments, your best shot is probably to do this as parallel second order section. Since the parallel sections are independent of each other, it's pretty straight forward to vectorize and it's also a little cheaper: each section has a complex conjugate pole pair but only one real zero.

Things get a bit more tricky if you have real poles or multiple poles at the same location: this can still be done, but it makes the code more awkward.

In order to calculate the coefficients for the parallel sections you need to do a partial fraction expansion. The good news: Matlab has a function for this, it's called $$residuez()$$. The bad news: it's not a very good implementation and will often fail with similar numerical problems as you get with your filtering. You can try it on your filter and post another question if residuez() fails for your particular example.

First of all, what is the order of your IIR filter? The highest order I have ever used was an order-10 IIR filter for a control loop application. I feel like it is unlikely that you need more that this.

Second, it is a good idea to split your filter in second-order-sections (SOS) and cascade them , this usually fix most issues.

https://www.dsprelated.com/showarticle/1137.php

You can also split your filter in second-order-sections and put them in parallel and add their ouputs too.

• Thanks Ben. I've gotten an 8th order filter working and it's not quite enough for my application, and a 20th order filter, which was enough. However, once I started playing with the band the filter worked on, even 8th order filters are failing. I'm looking into SOS, but I'm not sure if it will work for me. I like SS representation because I can do it in a few large matrix operations, and I'm not sure I can do that with SOS. – Jack Aug 1 '19 at 15:03
• you split your order-20 IIR filter in 10 separate order-2 IIR filter. Afterwards, you cascade them. The output of the first filter will be the input of the second filter, until the output of your 10th filter will be the output you want all along. – Ben Aug 1 '19 at 15:10
• Right, and that would be 10x as many matrix operations. I have specialized hardware for matrix operations, so I can handle 20th order all in one go, but I don't think I can run more than 1 while staying in real-time. – Jack Aug 1 '19 at 15:15
• The matrices will be much smaller so I'm not sure the actual complexity will increase. – Ben Aug 1 '19 at 15:18
• If I convert it in number of multiplications : an order-20 IIR filter in direct implementation will require 41 multiplications. an order-20 IIR filter in cascaded second-order-sections will require 50 multiplications but it will be more numerically stable. – Ben Aug 1 '19 at 15:20