Filters are important, they make water safe to drink. But if you're majoring in Electrical/Electronics engineering, they probably mean something different to you. For starters let us think of our filter as a black box with one input and one output. You input something and something comes out. There are an infinite number of things that could happen inside that box.

I recommend that the reader be familiar with extremely basic aspects of signal processing, like the delta function and the Fourier transform among other things for this blog to truly make sense.

# Basics

To somewhat lessen the scope of what can happen inside that black box, we introduce two major constraints,

- Linearity - "The sum of outputs is equal to the output of sums"
- Time Invariance - This essentially means that the performance of our black box does not depend explicitly on time.

Once these two conditions are satisfied, we can conveniently refer to our black box as an LTI system, LTI being Linear, Time-Invariant.

$$

Impulse \hspace{0.25cm} response \hspace{0.25cm} of \hspace{0.25cm} a \hspace{0.25cm} filter \hspace{0.25cm} : \hspace{0.5cm} h[n]
$$

I often heard my professors say, "A fundamental result is that the impulse response characterizes a filter". Turns out that the impulse response of a filter is nothing but the output of the filter when the input is a delta function.

But why is the impulse response so important - once you have the impulse response of a filter, you simply convolve the impulse response with the input of your filter and you get the output. Convolve once again is just a fancy name given to a particular summation because it is used so often in signal processing.

Convolution is represented by the asterisk(*) operator which is why most signal processing texts simply do not use it to represent multiplication.

$$ y[n] = x[n]*h[n] $$

Here, y[n] is the output of the filter, and x[n] is the input to the filter.

# Analysis

If you're familiar with a little bit of signal processing, you probably know about the time and frequency domains. To classify filters, we first take a peek at the impulse response of a filter from the time domain :

- FIR/ Finite Impulse Response: the impulse response is finite in nature
- IIR/ Infinite Impulse Response: duh!

Since we covered time, it only makes sense to see what the frequency domain has to offer: Frequency response of a filter is determined by the Discrete-Time Fourier Transform (DTFT) of its Impulse Response, as with any complex quantity once we obtain the frequency response we divide it into a magnitude and a phase term. The magnitude of the frequency response determines if the filter is going to be low-pass, high-pass, or band-pass. A low-pass filter allows low frequencies to pass and similarly for high-pass and band-pass.

*A neat observation is that if the phase term of the frequency response is proportional to the frequency or in other words is a "pure complex exponential", the filter simply adds a delay to our signal.*

Ideally, you would want your filter to have zero phase, so as to not add any delay to the output of the filter. You would also want to infinitely attenuate all frequencies that are outside the passband so that none of them show up in the output. But when we take a look at the impulse response of an ideal filter, the impulse response is not absolutely summable and thus isn't BIBO stable. BIBO stands for Bounded Input Bounded Output, to know more about the stability of a filter, check out this link.

# Windows

The impulse response of an ideal filter extends infinitely in either direction on the X-axis, logic dictates that since the infinite extension of the impulse response is the root cause of our inability to design an ideal digital filter, we truncate it.

This is where *windows* come in.
A window can be thought of as a sequence that we multiply our impulse response with to truncate it

For simplicity, we can assume our window to be a rectangular window, which is defined as :
$$
\begin{align}
w[n] & = 1 \hspace{0.5cm} for \hspace{0.5cm}|n|<=N \\
& = 0 \hspace{0.5cm} otherwise \\
\end{align}

$$
Our new impulse response becomes
$$
\hat{h} [n] = h[n]w[n]
$$

*Note: there are many other window functions out there namely, Triangular, Hamming, Hanning, and so on.*

# The Z Transform

For designing filters, we are interested in the H[e^jω], the Fourier transform of the impulse response h[n]. So we use something known as the Z transform. We already know $$ y[n] = x[n]*h[n] $$ We take the z transform on both sides. A little mathematical background about the Z transform can be found here.

We get
$$
\begin{align}
Z(y[n]) = Z(h[n]*x[n])\\
Y(z) = H(z)X(z)\\
H(z) = Y(z)/X(z)
\end{align}

$$

H(z) is known as the transfer function and when we input $$ z = e^{jω} $$ in the transfer function. We get the frequency response of the filter.

We can consider H(z) to be a ratio of two polynomials which explains why we cannot have sharp transition bands as it would introduce discontinuity and polynomials are continuous by definition.

# Filter Specification

Every time we would go about designing a filter we would essentially have 2 constraints

- Frequency Response - Which frequencies do we want/ don't want.
- Phase - No phase, linear phase, etc

And practically we also have a third constrain which is the computation power available to us.

The image shows the ideal frequency response of a low-pass filter.

Since our transfer function is a polynomial we can't have the immediate transition from passband to stopband.

A practical low pass filter has a frequency response that looks like this

Both images have been taken from this book.

The ripples in the passband and the width of the transition band can both be minimized as we increase filter order. But increase in filter order can prove to be computationally expensive, which is why we have the third constraint - computational power.

# Filter Design

Remember when I said that the H(z) is equal to a polynomial; designing a filter involves calculating the various coefficients of the said polynomial, but thankfully due to various numerical packages available in MATLAB and Python. We never really need to do that. In fact, for the most part, you'll find yourself using a trial and error approach - you'll use some premade filter and alter the parameters till it satisfies your requirements.

That's it for now folks. Do let me know if I've published some wrong information, or you have some suggestions.