<?xml version="1.0" encoding="UTF-8" standalone="yes"?><oembed><version><![CDATA[1.0]]></version><provider_name><![CDATA[The ryg blog]]></provider_name><provider_url><![CDATA[https://fgiesen.wordpress.com]]></provider_url><author_name><![CDATA[fgiesen]]></author_name><author_url><![CDATA[https://fgiesen.wordpress.com/author/fgiesen/]]></author_url><title><![CDATA[Z-transform done quick]]></title><type><![CDATA[link]]></type><html><![CDATA[<p>The Z-transform is a standard tool in signal processing; however, most descriptions of it focus heavily on the mechanics of manipulation and don&#8217;t give any explanation for what&#8217;s going on. In this post, my goal is to cover only the basics (just enough to understand standard FIR and IIR filter formulations) but make it a bit clearer what&#8217;s actually going on. The intended audience is people who&#8217;ve seen and used the Z-transform before, but never understood why the terminology and notation is the way it is.</p>
<h3>Polynomials</h3>
<p>In an earlier draft, I tried to start directly with the standard Z-transform, but that immediately brings up a bunch of technicalities that make matters more confusing than necessary. Instead, I&#8217;m going to start with a simpler setting: let&#8217;s look at polynomials.</p>
<p>Not just any polynomials, mind. Say we have a finite sequence of real or complex numbers <img src="https://s0.wp.com/latex.php?latex=a_0%2C+%5Cdots%2C+a_n&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=a_0%2C+%5Cdots%2C+a_n&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=a_0%2C+%5Cdots%2C+a_n&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="a_0, &#92;dots, a_n" class="latex" />. Then we can define a corresponding polynomial that has the values in that sequence as its coefficients:</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+A+%3A%3D+%5Csum_%7Bi%3D0%7D%5En+a_i+x%5Ei&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+A+%3A%3D+%5Csum_%7Bi%3D0%7D%5En+a_i+x%5Ei&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+A+%3A%3D+%5Csum_%7Bi%3D0%7D%5En+a_i+x%5Ei&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle A := &#92;sum_{i=0}^n a_i x^i" class="latex" />.</p>
<p>and of course there&#8217;s also a corresponding polynomial function A(x) that plugs in concrete values for x. Polynomials are closed under addition and scalar multiplication (both componentwise, or more accurately in this case, coefficient-wise) so they are a vector space and we can form linear combinations <img src="https://s0.wp.com/latex.php?latex=%5Clambda+A+%2B+%5Cmu+B&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Clambda+A+%2B+%5Cmu+B&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Clambda+A+%2B+%5Cmu+B&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;lambda A + &#92;mu B" class="latex" />. That&#8217;s reassuring, but not particularly interesting. What is interesting is the other fundamental operation we can do with polynomials: Multiply them. Let&#8217;s say we multiply two polynomials A and B to form a third polynomial C, and we want to find the corresponding coefficients:</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+AB+%3D+%5Cleft%28+%5Csum_%7Bi%3D0%7D%5En+a_i+x%5Ei+%5Cright%29+%5Cleft%28+%5Csum_%7Bi%3D0%7D%5Em+b_i+x%5Ei+%5Cright%29+%3D+%5Csum_%7Bi%3D0%7D%5En+%5Csum_%7Bj%3D0%7D%5Em+a_i+b_j+x%5E%7Bi%2Bj%7D+%3D+%5Csum_%7Bk%3D0%7D%5E%7Bn%2Bm%7D+c_k+x%5Ek+%3D+C&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+AB+%3D+%5Cleft%28+%5Csum_%7Bi%3D0%7D%5En+a_i+x%5Ei+%5Cright%29+%5Cleft%28+%5Csum_%7Bi%3D0%7D%5Em+b_i+x%5Ei+%5Cright%29+%3D+%5Csum_%7Bi%3D0%7D%5En+%5Csum_%7Bj%3D0%7D%5Em+a_i+b_j+x%5E%7Bi%2Bj%7D+%3D+%5Csum_%7Bk%3D0%7D%5E%7Bn%2Bm%7D+c_k+x%5Ek+%3D+C&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+AB+%3D+%5Cleft%28+%5Csum_%7Bi%3D0%7D%5En+a_i+x%5Ei+%5Cright%29+%5Cleft%28+%5Csum_%7Bi%3D0%7D%5Em+b_i+x%5Ei+%5Cright%29+%3D+%5Csum_%7Bi%3D0%7D%5En+%5Csum_%7Bj%3D0%7D%5Em+a_i+b_j+x%5E%7Bi%2Bj%7D+%3D+%5Csum_%7Bk%3D0%7D%5E%7Bn%2Bm%7D+c_k+x%5Ek+%3D+C&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle AB = &#92;left( &#92;sum_{i=0}^n a_i x^i &#92;right) &#92;left( &#92;sum_{i=0}^m b_i x^i &#92;right) = &#92;sum_{i=0}^n &#92;sum_{j=0}^m a_i b_j x^{i+j} = &#92;sum_{k=0}^{n+m} c_k x^k = C" class="latex" />.</p>
<p>To find the coefficients of C, we simply need to sum across all the combinations of indices i, j such that i+j=k, which of course means that j=k-i:</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+c_k+%3D+%5Csum_i+a_i+b_%7Bk-i%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+c_k+%3D+%5Csum_i+a_i+b_%7Bk-i%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+c_k+%3D+%5Csum_i+a_i+b_%7Bk-i%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle c_k = &#92;sum_i a_i b_{k-i}" class="latex" />.</p>
<p>When I don&#8217;t specify a restriction on the summation index, that simply means &#8220;sum over all i for which the right-hand side is well-defined&#8221;. And speaking of notation, in the future, I don&#8217;t want to give a name to every individual expression just so we can look at the coefficients; instead, I&#8217;ll just write <img src="https://s0.wp.com/latex.php?latex=%5Bx%5Ek%5D%5C+AB&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Bx%5Ek%5D%5C+AB&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Bx%5Ek%5D%5C+AB&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="[x^k]&#92; AB" class="latex" /> to denote the coefficient of x<sup>k</sup> in the product of A and B &#8211; which is of course our c<sub>k</sub>. Anyway, this is simply the <a href="http://en.wikipedia.org/wiki/Convolution#Discrete_convolution">discrete convolution</a> of the two input sequences, and we&#8217;re gonna milk this connection for all it&#8217;s worth.</p>
<p>Knowing nothing but this, we can already do some basic filtering in this form if we want to: Suppose our a<sub>i</sub> encode a sampled sound effect. A again denotes the corresponding polynomial, and let&#8217;s say <img src="https://s0.wp.com/latex.php?latex=B+%3D+%281+%2B+x%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=B+%3D+%281+%2B+x%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=B+%3D+%281+%2B+x%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="B = (1 + x)" class="latex" />, corresponding to the sequence (1, 1). Then C=AB computes the convolution of A with the sequence (1, 1), i.e. each sample and its immediate successor are summed (this is a simple but unnormalized low-pass filter). Now so far, we&#8217;ve only really substituted one way to write convolution for another. There&#8217;s more to the whole thing than this, but for  that we need to broaden our setting a bit.</p>
<h3>Generating functions</h3>
<p>The next step is to get rid of the fixed-length limitation. Instead of a finite sequence, we&#8217;re now going to consider potentially infinite sequences <img src="https://s0.wp.com/latex.php?latex=%28a_i%29_%7Bi%3D0%7D%5E%5Cinfty&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%28a_i%29_%7Bi%3D0%7D%5E%5Cinfty&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%28a_i%29_%7Bi%3D0%7D%5E%5Cinfty&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="(a_i)_{i=0}^&#92;infty" class="latex" />. A finite sequence is simple one where all but finitely many of the a<sub>i</sub> are zero. Again, we can create a corresponding object that captures the whole sequence &#8211; only instead of a polynomial, it&#8217;s now a power series:</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+A+%3A%3D+%5Csum_%7Bi%3D0%7D%5E%5Cinfty+a_i+x%5Ei&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+A+%3A%3D+%5Csum_%7Bi%3D0%7D%5E%5Cinfty+a_i+x%5Ei&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+A+%3A%3D+%5Csum_%7Bi%3D0%7D%5E%5Cinfty+a_i+x%5Ei&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle A := &#92;sum_{i=0}^&#92;infty a_i x^i" class="latex" />.</p>
<p>And the corresponding function A(x) is called a<sub>i</sub>&#8216;s <em>generating function</em>. Now we&#8217;re dealing with infinite series, so if we want to plug in an actual value for x, we have to worry about convergence issues. For the time being, we won&#8217;t do so, however; we simply treat the whole thing as a formal power series (essentially, an &#8220;infinite-degree polynomial&#8221;), and all the manipulations I&#8217;ll be doing are justified in that context even if the corresponding series don&#8217;t converge.</p>
<p>Anyway, the properties described above carry over: we still have linearity, and there&#8217;s a multiplication operation (the Cauchy product) that is the obvious generalization of polynomial multiplication (in fact, the formula I&#8217;ve written above for the c<sub>k</sub> still applies) and again matches discrete convolution. So why did I start with polynomials in the first place if everything stays pretty much the same? Frankly, mainly so I don&#8217;t have to whip out both infinite sequences and power series in the second paragraph; experience shows that when I start an article that way, the only people who continue reading are the ones who already know everything I&#8217;m talking about anyway. Let&#8217;s see whether my cunning plan works this time.</p>
<p>So what do we get out of the infinite sequences? Well, for once, we can now work on infinite signals &#8211; or, more usually, signals with a length that is ultimately finite, but not known in advance, as occurs with real-time processing. Above we saw a simple summing filter, generated from a finite sequence. That sequence is the filter&#8217;s &#8220;impulse response&#8221;, so called because it&#8217;s the result you get when applying the filter to the unit impulse signal (1 0 0 &#8230;). (The generating function corresponding to that signal is simply &#8220;1&#8221;, so this shouldn&#8217;t be much of a surprise). Filters where the impulse response has finite length are called &#8220;finite impulse response&#8221; or FIR filters. These filters have a straight-up polynomial as their generating function. But we can also construct filters with an infinite impulse response &#8211; IIR filters. And those are the filters where we actually get something out of going to generating functions in the first place.</p>
<p>Let&#8217;s look at the simplest infinite sequence we can think of: (1 1 1 &#8230;), simply an infinite series of ones. The corresponding generating function is</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+G_1%28x%29+%3D+%5Csum_%7Bi%3D0%7D%5E%5Cinfty+x%5Ei&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+G_1%28x%29+%3D+%5Csum_%7Bi%3D0%7D%5E%5Cinfty+x%5Ei&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+G_1%28x%29+%3D+%5Csum_%7Bi%3D0%7D%5E%5Cinfty+x%5Ei&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle G_1(x) = &#92;sum_{i=0}^&#92;infty x^i" class="latex" /></p>
<p>And now let&#8217;s look at what we get when we convolve a signal a<sub>i</sub> with this sequence:</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+s_k+%3A%3D+%5Bx%5Ek%5D%5C+A+G_1%28x%29+%3D+%5Csum_%7Bi%3D0%7D%5Ek+a_i+%5Ccdot+1+%3D+%5Csum_%7Bi%3D0%7D%5Ek+a_i&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+s_k+%3A%3D+%5Bx%5Ek%5D%5C+A+G_1%28x%29+%3D+%5Csum_%7Bi%3D0%7D%5Ek+a_i+%5Ccdot+1+%3D+%5Csum_%7Bi%3D0%7D%5Ek+a_i&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+s_k+%3A%3D+%5Bx%5Ek%5D%5C+A+G_1%28x%29+%3D+%5Csum_%7Bi%3D0%7D%5Ek+a_i+%5Ccdot+1+%3D+%5Csum_%7Bi%3D0%7D%5Ek+a_i&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle s_k := [x^k]&#92; A G_1(x) = &#92;sum_{i=0}^k a_i &#92;cdot 1 = &#92;sum_{i=0}^k a_i" class="latex" /></p>
<p>Expanding out, we see that s<sub>0</sub> = a<sub>0</sub>, s<sub>1</sub> = a<sub>0</sub> + a<sub>1</sub>, s<sub>2</sub> = a<sub>0</sub> + a<sub>1</sub> + a<sub>2</sub> and so forth: convolution with G<sub>1</sub> generates a signal that, at each point in time, is simply the sum of all values up to that time. And if we actually had to compute things this way, this wouldn&#8217;t be very useful, because our filter would keep getting slower over time! Luckily, G<sub>1</sub> isn&#8217;t just an arbitrary function &#8211; it&#8217;s a <a href="http://en.wikipedia.org/wiki/Geometric_series">geometric series</a>, which means that <em>for concrete values x</em>, we can compute G<sub>1</sub>(x) as:</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+G_1%28x%29+%3D+%5Csum_%7Bi%3D0%7D%5E%5Cinfty+x%5Ei+%3D+%5Cfrac%7B1%7D%7B1+-+x%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+G_1%28x%29+%3D+%5Csum_%7Bi%3D0%7D%5E%5Cinfty+x%5Ei+%3D+%5Cfrac%7B1%7D%7B1+-+x%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+G_1%28x%29+%3D+%5Csum_%7Bi%3D0%7D%5E%5Cinfty+x%5Ei+%3D+%5Cfrac%7B1%7D%7B1+-+x%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle G_1(x) = &#92;sum_{i=0}^&#92;infty x^i = &#92;frac{1}{1 - x}" class="latex" /></p>
<p>and more generally, for arbitrary <img src="https://s0.wp.com/latex.php?latex=c+%5Cne+0&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=c+%5Cne+0&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=c+%5Cne+0&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="c &#92;ne 0" class="latex" /></p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+G_c%28x%29+%3D+%5Csum_%7Bi%3D0%7D%5E%5Cinfty+%28cx%29%5Ei+%3D+%5Csum_%7Bi%3D0%7D%5E%5Cinfty+c%5Ei+x%5Ei+%3D+%5Cfrac%7B1%7D%7B1+-+cx%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+G_c%28x%29+%3D+%5Csum_%7Bi%3D0%7D%5E%5Cinfty+%28cx%29%5Ei+%3D+%5Csum_%7Bi%3D0%7D%5E%5Cinfty+c%5Ei+x%5Ei+%3D+%5Cfrac%7B1%7D%7B1+-+cx%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+G_c%28x%29+%3D+%5Csum_%7Bi%3D0%7D%5E%5Cinfty+%28cx%29%5Ei+%3D+%5Csum_%7Bi%3D0%7D%5E%5Cinfty+c%5Ei+x%5Ei+%3D+%5Cfrac%7B1%7D%7B1+-+cx%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle G_c(x) = &#92;sum_{i=0}^&#92;infty (cx)^i = &#92;sum_{i=0}^&#92;infty c^i x^i = &#92;frac{1}{1 - cx}" class="latex" />.</p>
<p>If we apply the identity the other way round, we can turn such an expression of x back into a power series; in particular, when dealing with formal power series, the left-hand side is the definition of the expression on the right-hand side. This notation also suggests that G<sub>1</sub> is the inverse (wrt. convolution) of (1 &#8211; x), and more generally that G<sub>c</sub> is the inverse of (1 &#8211; cx). Verifying this makes for a nice exercise.</p>
<p>But what does that mean for us? It means that, given the expression</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+S+%3D+A+G_c%28x%29+%3D+%5Cfrac%7BA%7D%7B1+-+cx%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+S+%3D+A+G_c%28x%29+%3D+%5Cfrac%7BA%7D%7B1+-+cx%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+S+%3D+A+G_c%28x%29+%3D+%5Cfrac%7BA%7D%7B1+-+cx%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle S = A G_c(x) = &#92;frac{A}{1 - cx}" class="latex" /></p>
<p>we can treat it as the identity between power series that it is and multiply both sides by (1 &#8211; cx), giving:</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+S+%281+-+cx%29+%3D+A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+S+%281+-+cx%29+%3D+A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+S+%281+-+cx%29+%3D+A&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle S (1 - cx) = A" class="latex" /></p>
<p>and thus</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Bx%5Ek%5D%5C+S+%281+-+cx%29+%3D+s_k+-+c+s_%7Bk-1%7D+%3D+a_k+%5CLeftrightarrow+s_k+%3D+a_k+%2B+c+s_%7Bk-1%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Bx%5Ek%5D%5C+S+%281+-+cx%29+%3D+s_k+-+c+s_%7Bk-1%7D+%3D+a_k+%5CLeftrightarrow+s_k+%3D+a_k+%2B+c+s_%7Bk-1%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Bx%5Ek%5D%5C+S+%281+-+cx%29+%3D+s_k+-+c+s_%7Bk-1%7D+%3D+a_k+%5CLeftrightarrow+s_k+%3D+a_k+%2B+c+s_%7Bk-1%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle [x^k]&#92; S (1 - cx) = s_k - c s_{k-1} = a_k &#92;Leftrightarrow s_k = a_k + c s_{k-1}" class="latex" /></p>
<p>i.e. we can compute s<sub>k</sub> in constant time if we&#8217;re allowed to look at s<sub>k-1</sub>. In particular, for the c=1 case we started with, this just means the obvious thing: don&#8217;t throw the partial sum away after every sample, instead just keep adding the most recent sample to the running total.</p>
<p>And here&#8217;s the thing: that&#8217;s everything you need to compute convolutions with almost any sequence that has a rational generating function, i.e. it&#8217;s a quotient of polynomials <img src="https://s0.wp.com/latex.php?latex=P%28x%29+%2F+Q%28x%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=P%28x%29+%2F+Q%28x%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=P%28x%29+%2F+Q%28x%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="P(x) / Q(x)" class="latex" />. Using the same trick as above, it&#8217;s easy to see what that means computationally. Say that <img src="https://s0.wp.com/latex.php?latex=P%28x%29+%3D+p_0+%2B+p_1+x+%2B+%5Ccdots+%2B+p_n+x%5En&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=P%28x%29+%3D+p_0+%2B+p_1+x+%2B+%5Ccdots+%2B+p_n+x%5En&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=P%28x%29+%3D+p_0+%2B+p_1+x+%2B+%5Ccdots+%2B+p_n+x%5En&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="P(x) = p_0 + p_1 x + &#92;cdots + p_n x^n" class="latex" /> and <img src="https://s0.wp.com/latex.php?latex=Q%28x%29+%3D+q_0+%2B+q_1+x+%2B+%5Ccdots+%2B+q_m+x%5Em&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=Q%28x%29+%3D+q_0+%2B+q_1+x+%2B+%5Ccdots+%2B+q_m+x%5Em&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=Q%28x%29+%3D+q_0+%2B+q_1+x+%2B+%5Ccdots+%2B+q_m+x%5Em&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="Q(x) = q_0 + q_1 x + &#92;cdots + q_m x^m" class="latex" />. If our signal has the generating function A(x), then computing the filtered signal S boils down to evaluating <img src="https://s0.wp.com/latex.php?latex=S%28x%29+%3A%3D+A%28x%29+P%28x%29+%2F+Q%28x%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=S%28x%29+%3A%3D+A%28x%29+P%28x%29+%2F+Q%28x%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=S%28x%29+%3A%3D+A%28x%29+P%28x%29+%2F+Q%28x%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="S(x) := A(x) P(x) / Q(x)" class="latex" />. Along the same lines as before, we have</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Bx%5Ek%5D%5C+S+%28q_0+%2B+q_1+x+%2B+%5Ccdots+%2B+q_m+x%5Em%29+%3D+%5Bx%5Ek%5D+A+%28p_0+%2B+%5Ccdots+%2B+p_n+x%5En%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Bx%5Ek%5D%5C+S+%28q_0+%2B+q_1+x+%2B+%5Ccdots+%2B+q_m+x%5Em%29+%3D+%5Bx%5Ek%5D+A+%28p_0+%2B+%5Ccdots+%2B+p_n+x%5En%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Bx%5Ek%5D%5C+S+%28q_0+%2B+q_1+x+%2B+%5Ccdots+%2B+q_m+x%5Em%29+%3D+%5Bx%5Ek%5D+A+%28p_0+%2B+%5Ccdots+%2B+p_n+x%5En%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle [x^k]&#92; S (q_0 + q_1 x + &#92;cdots + q_m x^m) = [x^k] A (p_0 + &#92;cdots + p_n x^n)" class="latex" /></p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5CLeftrightarrow+q_0+s_k+%2B+q_1+s_%7Bk-1%7D+%2B+%5Ccdots+%2B+q_m+s_%7Bk-m%7D+%3D+p_0+a_k+%2B+%5Ccdots+%2B+p_n+a_%7Bk-n%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5CLeftrightarrow+q_0+s_k+%2B+q_1+s_%7Bk-1%7D+%2B+%5Ccdots+%2B+q_m+s_%7Bk-m%7D+%3D+p_0+a_k+%2B+%5Ccdots+%2B+p_n+a_%7Bk-n%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5CLeftrightarrow+q_0+s_k+%2B+q_1+s_%7Bk-1%7D+%2B+%5Ccdots+%2B+q_m+s_%7Bk-m%7D+%3D+p_0+a_k+%2B+%5Ccdots+%2B+p_n+a_%7Bk-n%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle &#92;Leftrightarrow q_0 s_k + q_1 s_{k-1} + &#92;cdots + q_m s_{k-m} = p_0 a_k + &#92;cdots + p_n a_{k-n}" class="latex" /></p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5CLeftrightarrow+q_0+s_k+%3D+%5Cleft%28%5Csum_%7Bj%3D0%7D%5En+p_j+a_%7Bk-j%7D%5Cright%29+-+%5Cleft%28%5Csum_%7Bj%3D1%7D%5Em+q_j+s_%7Bk-j%7D%5Cright%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5CLeftrightarrow+q_0+s_k+%3D+%5Cleft%28%5Csum_%7Bj%3D0%7D%5En+p_j+a_%7Bk-j%7D%5Cright%29+-+%5Cleft%28%5Csum_%7Bj%3D1%7D%5Em+q_j+s_%7Bk-j%7D%5Cright%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5CLeftrightarrow+q_0+s_k+%3D+%5Cleft%28%5Csum_%7Bj%3D0%7D%5En+p_j+a_%7Bk-j%7D%5Cright%29+-+%5Cleft%28%5Csum_%7Bj%3D1%7D%5Em+q_j+s_%7Bk-j%7D%5Cright%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle &#92;Leftrightarrow q_0 s_k = &#92;left(&#92;sum_{j=0}^n p_j a_{k-j}&#92;right) - &#92;left(&#92;sum_{j=1}^m q_j s_{k-j}&#92;right)" class="latex" /></p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5CRightarrow+s_k+%3D+%5Cfrac%7B1%7D%7Bq_0%7D+%5Cleft%28%5Csum_%7Bj%3D0%7D%5En+p_j+a_%7Bk-j%7D+-+%5Csum_%7Bj%3D1%7D%5Em+q_j+s_%7Bk-j%7D%5Cright%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5CRightarrow+s_k+%3D+%5Cfrac%7B1%7D%7Bq_0%7D+%5Cleft%28%5Csum_%7Bj%3D0%7D%5En+p_j+a_%7Bk-j%7D+-+%5Csum_%7Bj%3D1%7D%5Em+q_j+s_%7Bk-j%7D%5Cright%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5CRightarrow+s_k+%3D+%5Cfrac%7B1%7D%7Bq_0%7D+%5Cleft%28%5Csum_%7Bj%3D0%7D%5En+p_j+a_%7Bk-j%7D+-+%5Csum_%7Bj%3D1%7D%5Em+q_j+s_%7Bk-j%7D%5Cright%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle &#92;Rightarrow s_k = &#92;frac{1}{q_0} &#92;left(&#92;sum_{j=0}^n p_j a_{k-j} - &#92;sum_{j=1}^m q_j s_{k-j}&#92;right)" class="latex" />.</p>
<p>So again, we can compute the signal incrementally using a fixed amount of work (depending only on n and m) for every sample, provided that q<sub>0</sub> isn&#8217;t zero. The question is, do these rational functions still have a corresponding series expansion? After all, this is what we need to employ generating functions in the first place. Luckily, the answer is yes, again provided that q<sub>0</sub> isn&#8217;t zero. I&#8217;ll skip describing how exactly this works since we&#8217;ll be content to deal directly with the factored rational function form of our generating functions from here on out; if you want more details (and see just how useful the notion of a generating function turns out to be for all kinds of problems!), I recommend you look at the excellent <a href="http://en.wikipedia.org/wiki/Concrete_Mathematics">&#8220;Concrete Mathematics&#8221;</a> by Graham, Knuth and Patashnik or the by now freely downloadable <a href="http://www.math.upenn.edu/~wilf/DownldGF.html">&#8220;generatingfunctionology&#8221;</a> by Wilf.</p>
<h3>At last, the Z-transform</h3>
<p>At this point, we already have all the theory we need for FIR and IIR filters, but with a non-standard notation, motivated by the desire to make the connection to standard polynomials and generating functions more explicit. Let&#8217;s fix that up: in signal processing, it&#8217;s customary to write a signal x as a function <img src="https://s0.wp.com/latex.php?latex=x+%3A+%5Cmathbb%7BZ%7D+%5Crightarrow+%5Cmathbb%7BR%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=x+%3A+%5Cmathbb%7BZ%7D+%5Crightarrow+%5Cmathbb%7BR%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=x+%3A+%5Cmathbb%7BZ%7D+%5Crightarrow+%5Cmathbb%7BR%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="x : &#92;mathbb{Z} &#92;rightarrow &#92;mathbb{R}" class="latex" /> (or <img src="https://s0.wp.com/latex.php?latex=x+%3A+%5Cmathbb%7BZ%7D+%5Crightarrow+%5Cmathbb%7BC%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=x+%3A+%5Cmathbb%7BZ%7D+%5Crightarrow+%5Cmathbb%7BC%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=x+%3A+%5Cmathbb%7BZ%7D+%5Crightarrow+%5Cmathbb%7BC%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="x : &#92;mathbb{Z} &#92;rightarrow &#92;mathbb{C}" class="latex" />), and it&#8217;s customary to write the argument in square brackets. So instead of dealing with sequences that consist of elements x<sub>n</sub>, we now have functions with values at integer locations x[n]. And the (unilateral) Z-transform of our signal x is now the function</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+X%28z%29+%3D+%5Cmathcal%7BZ%7D%28x%29+%3D+%5Csum_%7Bn%3D0%7D%5E%7B%5Cinfty%7D+x%5Bn%5D+z%5E%7B-n%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+X%28z%29+%3D+%5Cmathcal%7BZ%7D%28x%29+%3D+%5Csum_%7Bn%3D0%7D%5E%7B%5Cinfty%7D+x%5Bn%5D+z%5E%7B-n%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+X%28z%29+%3D+%5Cmathcal%7BZ%7D%28x%29+%3D+%5Csum_%7Bn%3D0%7D%5E%7B%5Cinfty%7D+x%5Bn%5D+z%5E%7B-n%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle X(z) = &#92;mathcal{Z}(x) = &#92;sum_{n=0}^{&#92;infty} x[n] z^{-n}" class="latex" />.</p>
<p>in other words, it&#8217;s basically a generating function, but this time the exponents are negative. I also assume that the signal is x[n] = 0 for all n&lt;0, i.e. the signal starts at some defined point and we move that point to 0. This doesn&#8217;t make any fundamental difference for the things I&#8217;ve discussed so far: all the properties discussed above still hold, and indeed all the derivations will still work if you mechanically substitute x<sup>k</sup> with z<sup>-k</sup>. In particular, anything involving convolutions still works exactly same. However it does make a difference if you actually plug in concrete values for z, which we are about to do. Also note that our variable is now z, not x. Customarily, &#8220;z&#8221; is used to denote complex variables, and this is no exception &#8211; more in a minute. Next, the Z-transform of our filter&#8217;s impulse response (which is essentially the filter&#8217;s generating function, except now we evaluate at 1/z) is called the &#8220;transfer function&#8221; and has the general form</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+H%28z%29+%3D+%5Cfrac%7BP%28z%5E%7B-1%7D%29%7D%7BQ%28z%5E%7B-1%7D%29%7D+%3D+%5Cfrac%7BY%28z%29%7D%7BX%28z%29%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+H%28z%29+%3D+%5Cfrac%7BP%28z%5E%7B-1%7D%29%7D%7BQ%28z%5E%7B-1%7D%29%7D+%3D+%5Cfrac%7BY%28z%29%7D%7BX%28z%29%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+H%28z%29+%3D+%5Cfrac%7BP%28z%5E%7B-1%7D%29%7D%7BQ%28z%5E%7B-1%7D%29%7D+%3D+%5Cfrac%7BY%28z%29%7D%7BX%28z%29%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle H(z) = &#92;frac{P(z^{-1})}{Q(z^{-1})} = &#92;frac{Y(z)}{X(z)}" class="latex" /></p>
<p>where P and Q are the same polynomials as above; these polynomials in z<sup>-1</sup> are typically written Y(z) and X(z) in the DSP literature. You can factorize the numerator and denominator polynomials to get the <em>zeroes</em> and <em>poles</em> of a filter. They&#8217;re important concepts in IIR filter design, but fairly incidental to what I&#8217;m trying to do (give some intution about what the Z-transform does and how it works), so I won&#8217;t go into further detail here.</p>
<h3>The Fourier connection</h3>
<p>One last thing: The relation of this all to frequency space, or: what do our filters actually do to frequencies? For this, we can use the <a href="http://en.wikipedia.org/wiki/Discrete-time_Fourier_transform">discrete-time Fourier transform</a> (DTFT, not to be confused with the <a href="http://en.wikipedia.org/wiki/Discrete_Fourier_transform">Discrete Fourier Transform</a> or DFT). The DTFT of a general signal x is</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Chat%7BX%7D%28%5Comega%29+%3D+%5Csum_%7Bn%3D-%5Cinfty%7D%5E%7B%5Cinfty%7D+x%5Bn%5D+e%5E%7B-i%5Comega+n%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Chat%7BX%7D%28%5Comega%29+%3D+%5Csum_%7Bn%3D-%5Cinfty%7D%5E%7B%5Cinfty%7D+x%5Bn%5D+e%5E%7B-i%5Comega+n%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Chat%7BX%7D%28%5Comega%29+%3D+%5Csum_%7Bn%3D-%5Cinfty%7D%5E%7B%5Cinfty%7D+x%5Bn%5D+e%5E%7B-i%5Comega+n%7D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle &#92;hat{X}(&#92;omega) = &#92;sum_{n=-&#92;infty}^{&#92;infty} x[n] e^{-i&#92;omega n}" class="latex" /></p>
<p>Now, in our case we&#8217;re only considering signals with x[n]=0 for n&lt;0, so we get</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Chat%7BX%7D%28%5Comega%29+%3D+%5Csum_%7Bn%3D0%7D%5E%5Cinfty+x%5Bn%5D+e%5E%7B-i%5Comega+n%7D+%3D+%5Csum_%7Bn%3D0%7D%5E%5Cinfty+x%5Bn%5D+%5Cleft%28e%5E%7Bi%5Comega%7D%5Cright%29%5E%7B-n%7D+%3D+X%28e%5E%7Bi%5Comega%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Chat%7BX%7D%28%5Comega%29+%3D+%5Csum_%7Bn%3D0%7D%5E%5Cinfty+x%5Bn%5D+e%5E%7B-i%5Comega+n%7D+%3D+%5Csum_%7Bn%3D0%7D%5E%5Cinfty+x%5Bn%5D+%5Cleft%28e%5E%7Bi%5Comega%7D%5Cright%29%5E%7B-n%7D+%3D+X%28e%5E%7Bi%5Comega%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Chat%7BX%7D%28%5Comega%29+%3D+%5Csum_%7Bn%3D0%7D%5E%5Cinfty+x%5Bn%5D+e%5E%7B-i%5Comega+n%7D+%3D+%5Csum_%7Bn%3D0%7D%5E%5Cinfty+x%5Bn%5D+%5Cleft%28e%5E%7Bi%5Comega%7D%5Cright%29%5E%7B-n%7D+%3D+X%28e%5E%7Bi%5Comega%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle &#92;hat{X}(&#92;omega) = &#92;sum_{n=0}^&#92;infty x[n] e^{-i&#92;omega n} = &#92;sum_{n=0}^&#92;infty x[n] &#92;left(e^{i&#92;omega}&#92;right)^{-n} = X(e^{i&#92;omega})" class="latex" /></p>
<p>which means we can compute the DTFT of a signal by evaluating its Z-transform at exp(i&omega;) &#8211; assuming the corresponding series of expression converges. Now, if the Z-transform of our signal is in general series form, this is just a different notation for the same thing. But for our rational transfer functions H(z), this is a big deal, because evaluating their values at given complex z is easy &#8211; it&#8217;s just a rational function, after all.</p>
<p>In fact, since we know that polynomial (and series) multiplication corresponds to convolution, we can now also easily see why convolution filters are useful to modify the frequency response (Fourier transform) of a signal: If we have a signal x with Z-transform X and the transfer function of a filter H, we get:</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%28X+%5Ccdot+H%29%28e%5E%7Bi%5Comega%7D%29+%3D+X%28e%5E%7Bi%5Comega%7D%29+H%28e%5E%7Bi%5Comega%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%28X+%5Ccdot+H%29%28e%5E%7Bi%5Comega%7D%29+%3D+X%28e%5E%7Bi%5Comega%7D%29+H%28e%5E%7Bi%5Comega%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%28X+%5Ccdot+H%29%28e%5E%7Bi%5Comega%7D%29+%3D+X%28e%5E%7Bi%5Comega%7D%29+H%28e%5E%7Bi%5Comega%7D%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle (X &#92;cdot H)(e^{i&#92;omega}) = X(e^{i&#92;omega}) H(e^{i&#92;omega})" class="latex" /></p>
<p>and in particular</p>
<p><img src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%7C%28X+%5Ccdot+H%29%28e%5E%7Bi%5Comega%7D%29%7C+%3D+%7CX%28e%5E%7Bi%5Comega%7D%29%7C+%7CH%28e%5E%7Bi%5Comega%7D%29%7C&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002" srcset="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%7C%28X+%5Ccdot+H%29%28e%5E%7Bi%5Comega%7D%29%7C+%3D+%7CX%28e%5E%7Bi%5Comega%7D%29%7C+%7CH%28e%5E%7Bi%5Comega%7D%29%7C&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002 1x, https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%7C%28X+%5Ccdot+H%29%28e%5E%7Bi%5Comega%7D%29%7C+%3D+%7CX%28e%5E%7Bi%5Comega%7D%29%7C+%7CH%28e%5E%7Bi%5Comega%7D%29%7C&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002&#038;zoom=4.5 4x" alt="&#92;displaystyle |(X &#92;cdot H)(e^{i&#92;omega})| = |X(e^{i&#92;omega})| |H(e^{i&#92;omega})|" class="latex" /></p>
<p>The first of these two equations is the discrete-time convolution theorem for Fourier transforms of signals: the DTFT of the convolution of the two signals is the point-wise product of the DTFTs of the original signal and the filter. The second shows us how filters can amplify or attenuate individual frequencies: if |H(e<sup>i&omega;</sup>)|&nbsp;&gt;&nbsp;1, frequency &omega; will be amplified in the filtered signal, and it it&#8217;s less than 1, it will be dampened.</p>
<h3>Conclusion and further reading</h3>
<p>The purpose of this post was to illustrate a few key concepts and the connections between them:</p>
<ul>
<li>Polynomial/series multiplication and convolution are the same thing.</li>
<li>The Z-transform is very closely related to generating functions, an extremely powerful technique for manipulating sequences.</li>
<li>In particular, the transfer function of a filter isn&#8217;t just some arbitrary syntactic convention to tie together the filter coefficients; there&#8217;s a direct connection to corresponding sequence manipulations.</li>
<li>The Fourier transform of filters is directly tied to the behavior of H(z) in the complex plane; computing the DTFT of an IIR filter&#8217;s impulse response directly would get messy, but the factored form of H(z) makes it easy.</li>
<li>With this background, it&#8217;s also fairly easy to see why filters work in the first place.</li>
</ul>
<p>I intentionally cover none of these aspects deeply; my experience is that most material on the subject does a great job of covering the details, at the expense of making it harder to see the big picture, so I wanted to try doing it the other way round. More details on series and generating functions can be found in the two books I cited above, and a good introduction to digital filters that supplies the details I omitted is Smith&#8217;s <a href="https://ccrma.stanford.edu/~jos/filters/">Introduction to Digital Filters</a>.</p>
]]></html></oembed>