Digital Filter Design
Digital Filter Design
| Digital Filter Design Methods | Output Response—Digital Filtering of Signals |
| Poles and Zeros of Digital Filters |
| LeastSquaresFilterKernel | create an FIR filter using the least-squares method |
| FrequencySamplingFilterKernel | create an FIR filter using frequency sampling |
| EquirippleFilterKernel | create an FIR filter using the equiripple method |
| ToDiscreteTimeModel | create an IIR digital filter from an analog prototype |
Least-Squares Method
This method obtains a finite impulse response (FIR) from a given prototype filter specification in the frequency domain by means of the inverse discrete-time Fourier transform.
The impulse response is obtained by taking the inverse discrete-time Fourier transform of the filter specification:
InverseFourierSequenceTransform[UnitBox[ω / 2.4], ω, n, FourierParameters -> {1, -1}]h = LeastSquaresFilterKernel[{"Lowpass", 1.2}, 15]This method minimizes the mean-squared error between the ideal specification and the resulting FIR filter:
Plot[{Abs[ListFourierSequenceTransform[h, x]], Piecewise[{{1, 0 ≤ x ≤ 1.2}}]}, {x, 0, π}, PlotRange -> All, Exclusions -> False, Filling -> {1 -> {2}}]The least-squares method is also known as the window-based method. The mean-squared error can be diminished by applying a smoothing window to the FIR returned by LeastSquaresFilterKernel.
win = Array[HannWindow, 15, {-0.5, 0.5}]h2 = win h;
Plot[Evaluate[20 Log[10, Abs[ListFourierSequenceTransform[#, x]]]& /@ {h, h2}], {x, 0, π}, ImageSize -> 300]Different windows return different attenuations. Select a window type by the degree of the desired attenuation.
With[{wins = {DirichletWindow, BartlettWindow, HannWindow, BlackmanWindow}},
f = FourierTransform[#[x], x, w]& /@ wins;
LogLinearPlot[Evaluate[20 Log[10, Abs[#] / Limit[#, w -> 0]]& /@ f], {w, 1, 100}, PlotRange -> {0, -100}, PlotLegends -> wins]]Frequency Sampling Method
Frequency sampling allows the creation of an FIR filter by specifying the filter's amplitude spectrum on the interval 0≤ ω≤ π at a finite number of uniformly spaced frequency locations.
t = Table[{x, UnitBox[x / (0.9 π)]}, {x, 0, 3, 2π / 11}]Show[{Plot[UnitBox[x / (0.9 π)], {x, 0, π}, Exclusions -> None], ListPlot[t, PlotRange -> All, PlotStyle -> {Red, PointSize[Large]}, Filling -> 0, FillingStyle -> Red]}]{frequencies, amplitudes} = Transpose[t];
FrequencySamplingFilterKernel[amplitudes, 1]Show[{ListPlot[t, PlotRange -> {{0, π}, {-0.2, 1.2}}, PlotStyle -> {Red, PointSize[Large]}, Filling -> Axis, AxesLabel -> {ω, None}, Ticks -> {Automatic, {0., 0.5, 1.}}], Plot[{UnitBox[ω / (0.9 π)], Evaluate[Abs[ListFourierSequenceTransform[FrequencySamplingFilterKernel[amplitudes, 1], ω]]]}, {ω, 0, π}, Exclusions -> None]}]Equiripple Method
The Parks–McClellan–Rabiner (1979) algorithm is one of the most popular methods of designing linear-phase FIR filters. It minimizes the maximum deviation from the desired ideal frequency response and results in filters with equal ripples in each of the bands of the filter.
EquirippleFilterKernel[{{{0., 0.05}, {.1, 0.15}, {0.18, 0.25}, {0.3, 0.36}, {0.41, 0.5}} 2 π, {0., 1., 0., 1., 0.}, {10., 1., 3., 1., 20.}}, 55]Plot[20 Log[10, Abs[ListFourierSequenceTransform[%, ω]]], {ω, 0, π}, PlotRange -> All, GridLines -> Automatic]Create a Digital Filter from an Analog Prototype
A popular method of creating digital filters is to transform analog prototypes to their digital equivalents using the bilinear transformation. The result is an infinite impulse response (IIR) filter, represented as a TransferFunctionModel.
| ToDiscreteTimeModel | discrete-time approximation of an analog filter |
tfa = TransferFunctionExpand[Chebyshev1FilterModel[{"Lowpass", {1., 3.}, {1., 40.}}, s]]//Choptfd = ToDiscreteTimeModel[tfa, 1, z, Method -> {"BilinearTransform"}]//ChopGraphicsRow[{Plot[Abs[tfd[E^I ω]]^2, {ω, 0, π}, AxesLabel -> {ω, None}, GridLines -> Automatic, AspectRatio -> 1 / 3], BodePlot[tfd, {0.1, N[π]}, GridLines -> Automatic, PlotLayout -> List]//First}]| TransferFunctionPoles | extract poles of analog filters |
| TransferFunctionZeros | extract zeros of analog filters |
h = LeastSquaresFilterKernel[{"Lowpass", 1.2}, 9];
H = ListZTransform[h, z]tf = TransferFunctionModel[H, z, SamplingPeriod -> 1]//TransferFunctionCancelzeros = Flatten@TransferFunctionZeros[tf]ListPlot[Transpose[{Re[zeros], Im[zeros]}], PlotRange -> 2.2{{-1, 1}, {-1, 1}}, PlotStyle -> {PointSize[Large]}, AxesOrigin -> {0, 0}, Epilog -> {Dashed, Pink, Circle[]}, AspectRatio -> Automatic]FIR Filters
| ListConvolve | convolve an FIR filter with data |
| ImageConvolve | convolve an FIR filter with image |
| DiscreteConvolve | symbolic convolution of two signals |
h = LeastSquaresFilterKernel[{"Lowpass", 0.5}, 21];
Plot[{Abs[ListFourierSequenceTransform[h, x]], Piecewise[{{1, 0 ≤ x ≤ .5}}]}, {x, 0, π}, PlotRange -> All, Exclusions -> False]a = ExampleData[{"Audio", "Apollo11ReturnSafely"}, "Audio"]res = Audio[ListConvolve[h, AudioData[a][[1]]], SampleRate -> AudioSampleRate[a]]img = [image];
row = ImageData[img, Interleaving -> False][[1, 100]];
ListLinePlot /@ {row, ListConvolve[(h / Total[h]), row, 12, 0]}ImageConvolve[img, Outer[Times, h, h]]IIR Filters
| RecurrenceFilter | apply an IIR filter to a signal |
| RecurrenceTable | iteratively solve the recurrence equation |
| OutputResponse | output response of a filter |
tfd = TransferFunctionModel[{{{1 + 3*z + 3*z^2 + z^3}},
-3 + 15*z - 25*z^2 + 21*z^3}, z,
SamplingPeriod -> 1];input = N@ArrayPad[{1}, {0, 20}];
RecurrenceFilter[tfd, input]RecurrenceFilter[{{21., -25., 15., -3. }, {1., 3., 3., 1.}}, input]Compute the impulse response using OutputResponse:
OutputResponse[tfd, input]Compute the impulse response by solving the corresponding recurrence equation model of the filter using RecurrenceTable:
Module[{x, y},
x[n_] := DiscreteDelta[n];
RecurrenceTable[{21y[n] - 25 y[n - 1] + 15 y[n - 2] - 3 y[n - 3] == x[n] + 3 x[n - 1] + 3 x[n - 2] + x[n - 3], y[-1] == 0, y[-2] == 0, y[-3] == 0}, y, {n, 0, 20}]//N]img = [image];
row = ImageData[img, Interleaving -> False][[1, 100]];
ListLinePlot /@ {row, RecurrenceFilter[tfd, row]}RecurrenceFilter[tfd, img]