4.2.5. The Z-Operator¶
\(\newcommand{\op}[1]{\mathsf #1}\) \(\newcommand{\ztarrow}{\stackrel{\op Z}{\longrightarrow}}\) \(\newcommand{\z}{\op z}\)
The Z-transform takes a sequence \(x[n]\) and returns a function \(X(z)\). In the z-domain we have seen that shifting a signal \(x[n]\) over \(n_0\), resulting in \(x[n-n_0]\), leads to the Z-transform \(z^{-n_0}X(z)\) where \(X(z)\) is the transform of the original signal.
This observation has lead to the introduction of the \(\z\)-operator that takes a discrete signal \(x\) and shifts it:
With this algebraic notation of a shift, together with multiplications and summations this is all we need to characterize /all/ linear translation invariant filters.
Note that shifting over 3 samples corresponds with the operator \(\z \z \z = \z^3\) or in general:
Evidently the operator \(\z^{-1}\) corresponds with a shift in the opposite direction and thus the above equation may be interpreted for both positive and negative (integer) values of \(m\).
A simple non-causal running average filter over 5 samples can be defined as the operator:
Using this filter to process a signal \(x\) is denoted as \(\op f x\) or \(\op f(x)\) where we assume \(x\) is a discrete signal.
A recursive band stop filter is defined with:
Using the \(\z\) operator we may write:
because now all signals are indexed at \(n\) we may leave the index out to obtain the expression that is valid for all \(n\):
or equivalently:
This band stop filter thus can be formally defined as:
and of course in the definition of the filter \(\op f\) you recognize the Z-transform of the impulse response of the filter characterized with the Z-transform:
Please note however that \(H(z)\) is not the filter \(\op f\). In the expression for \(H(z)\), \(z\) is a complex number whereas in the expression for \(\op f\), \(\z\) is an operator. The operator notation for \(\op f\) is a symbolic notation. It can be implemented in practice using the difference equation we started with.
Using the \(\z\) operator to define discrete LTI filters is nowadays often used. In fact even software is written in which the \(\z\) operator notation plays a central role. Below we give some examples using the ‘audiolazy’ Python package.
1import numpy as np
2import matplotlib.pyplot as plt
3from audiolazy import z
4
5H = (z**2-1.9*z+1)/(z**2-1.8*z+0.9);
6H.zplot().savefig('source/figures/hzplot.pdf');
7H.plot().savefig('source/figures/hfplot.pdf');
Note that in the code given here the function savefig() is used to save the figure in a file. In an interactive session you can use show() instead.
Although conceptually nice, audiolazy still lacks soms of the standard filters. A lot of these standard filters are available in scipy.signal. In the lecture notes on filter design some examples of the use of scipy will be given.
Todo
look at the status of audiolazy