y[t] = a*x[t] + b*x[t-1]
Whereas a simple IIR filter might look like: y[t] = a*x[t] + b*y[t-1]
In the first equation, only two input samples (x[t] and x[t-1]) are used to compute each output sample. A sharp "impulse" at x[0] will only affect the values of y[0] and y[1]. That's what makes it an FIR filter—the number of output samples affected by an impulse is finite.On the other hand, the second equation has a y[t-1] term on the right hand side. Each output sample feeds back into the next one. To see what this looks like purely in terms of x samples, you can substitute using the equation for y[t], then multiply:
y[t] = a*x[t] + b*y[t-1]
y[t] = a*x[t] + b*(a*x[t-1] + b*y[t-2])
y[t] = a*x[t] + b*a*x[t-1] + b^2*y[t-2]
y[t] = a*x[t] + b*a*x[t-1] + b^2*(a*x[t-2] + b*y[t-3])
y[t] = a*x[t] + b*a*x[t-1] + b^2*a*x[t-2] + b^3*y[t-3]
...
Eventually you'll get the sum (assuming the samples start at x[0]): y[t] = sum from n=0 to t of b^n*a*x[t-n]
The sum ranges over the entire array of samples, all the way back to the beginning. Each input sample from x influences every output sample afterward. The output for an impulse—a single positive x[0] sample followed by x[1] = x[2] = ... = 0—is y[t] = b^t*a*x[0]
Since these samples are non-zero for all t (though decaying exponentially according to the value of b), the second equation describes a filter with infinite impulse response. def touchDown():
velocity = 0
lastTime = now
def touchMoved(from, to):
velocity = (to - from) / (now - lastTime)
lastTime = now
def touchFinished():
if velocity.x > threshold:
performGesture()
You test it out, and discover that the gesture is kind of flaky. Sometimes it works properly, but just as often it fails when it feels like it should have worked. It turns out that maintaining a constant velocity is hard—as your finger moves across the screen, the velocity can fluctuate around between samples. The test in touchFinished() looks at only the last sample taken, which is often the worst, as your finger has just lifted off from the screen.So instead of just looking at the last velocity, you keep track of a "smoothedVelocity" which averages your velocity samples together:
def touchDown():
smoothedVelocity = 0
lastTime = now
def touchMoved(from, to):
velocity = (to - from) / (now - lastTime)
smoothedVelocity = 0.25 * velocity + 0.75 * smoothedVelocity
lastTime = now
def touchFinished():
if smoothedVelocity.x > threshold:
performGesture()
With this change, your smoothedVelocity moves a bit toward the measured velocity with each sample, but won't jump directly there. This feels a lot more predictable. Stopping your finger momentarily as it lifts off the screen won't stop the gesture from being performed, for example.The smoothedVelocity code implements a low-pass IIR filter (it filters out the high-frequency fluctuations while letting the lower-frequency motion pass through). You could also imagine just keeping the last 2 velocities and averaging them together at the end: that would be an FIR filter.
When you want to filter some data you often start by defining the response you're after, for example for a sub-woofer output you might want a low-pass filter that cuts off frequencies higher than 250 Hz.
Then you use some math to figure out the filter coefficients that will give you that response. For many (all?) filters you can get away with far fewer coefficients, often orders of magnitude like 4 vs 1024, if you go for an IIR filter rather than a FIR filter. This of course makes it far cheaper computationally to implement.
IIR filters have some downsides though compared to FIR, for one an impulse "never goes away" (at least in theory) since there's always some of it begin fed back into the next step. It's also difficult to make them have linear phase response, which can be important in certain settings.
With IIR, you typically have much lower latency because it requires many fewer stages to get the same-ish transfer function. Tradeoffs: ringing, perhaps problematic phase response, more complicated synthesis problem.
https://twitter.github.io/finagle/guide/Clients.html#power-o...
https://blog.cloudflare.com/i-wanna-go-fast-load-balancing-d...
https://www.nginx.com/blog/choosing-nginx-plus-load-balancin...
Finite Impulse Response means that the output of the filter will eventually go to zero - after a finite duration. Infinite Impulse Response means that the output of the filter may never go to zero.
It can be proved that FIR and IIR filters have different properties; the article mentions that IIR filters are necessarily stateful, for instance.