Group delay (MATLAB $\tt grpdelay$) I have been trying to figure out how it is I have an IIR filter with large negative group delay.  It's my understanding that if a filter is causal and stable, the group delay can't be negative at all frequencies.  Is this correct?

The essence of my problem can be seen in the following MATLAB code.  This first filter gives four poles inside the unit circle and four zeros at zero.  The group delay is both positive and negative with a mean of zero.  I believe the contribution of each pole and zero adds and negates one sample of average group delay, respectively.


(1a) grpdelay(1,[1 0 0 0 .1],100000,'whole')


Now, if I create a semi-stable filter, the poles on the unit circle contribute 1/2 sample, so the average group delay is -2.  Actually it's -2 everywhere.  If the poles are outside the unit circle, there's no contribution; so, the average is -4 for the four zeros at zero.


(1b) grpdelay(1,[1 0 0 0 1],100000,'whole')
(1c) grpdelay(1,[1 0 0 0 2],100000,'whole')


OK so far.  Now if I just change the last coefficient to be complex valued, I believe this just rotates the poles, but now there is no contribution for poles inside the circle, poles on the circle subtract 1/2 sample instead of adding, and poles outside the circle subtract 1 sample.  And thus, you get negative group delay everywhere, even when the poles are inside the circle.


(2a) grpdelay(1,[1 0 0 0 .1j],100000,'whole')
(2b) grpdelay(1,[1 0 0 0 1j],100000,'whole')
(2c) grpdelay(1,[1 0 0 0 2j],100000,'whole')


I briefly glanced at the code for grpdelay but did not make a serious attempt to understand it.  Also, if you flip this around and use an FIR filter, changing the last coefficient to complex does not change the average group delay contribution by each zero.


Example (1a):


Example (2a):
This is a bug, either in your code, or in your version of the Matlab function grpdelay. As you correctly pointed out, making the last denominator coefficient imaginary just rotates the pole-zero diagram. This means that for the given example, the zeros stay where they were (in the origin), and the pole angles are rotated by $\pi/8$; or course, the pole radii remain unchanged.

For the group delay function this means that it only gets shifted (along the frequency axis), but its maximum and minimum values (and its overall shape) must remain the same.

Using Octave I get the expected result:


g1 = grpdelay(1,[1 0 0 0 .1],1000,'whole');
g2 = grpdelay(1,[1 0 0 0 .1j],1000,'whole');
plot([g1(:),g2(:)]), axis([0,1000,-.4,.5]), grid on