FilterFrequencyResponse - Maple Help

SignalProcessing

 FilterFrequencyResponse
 determine the response of an FIR or IIR digital filter from taps

 Calling Sequence FilterFrequencyResponse( A, options ) FilterFrequencyResponse( A, B, options )

Parameters

 A - 1-D rtable or list of numeric values for the coefficients of the numerator of the transfer function. B - (optional) 1-D rtable or list of numeric values for the coefficients of the denominator of the transfer function. The default is NULL.

Options

 • fftnormalization: (optional) One of none, symmetric, or full, indicates the normalization to be applied when using the Fast Fourier Transform (FFT). The default is symmetric.
 • magnitudeplotoptions: (optional) Additional plot options to be passed when creating the plot of the magnitudes. The default is [].
 • phaseplotoptions: (optional) Additional plot options to be passed when creating the plot of the phases. The default is [].
 • phaseunit: (optional) Specifies the unit of angle for the phases. The default is Unit(degrees). Either of the forms algebraic or Unit(algebraic) is accepted, and the unit must be convertible to a valid unit of angle.
 • samplerate: (optional) Positive numeric value for the sampling rate. The default is NULL.
 • size: (optional) Positive integer larger than 1, which specifies the computed size of the response, magnitudes, and phases Vectors. The default is the smallest power of 2 that is greater than or equal to all of 512, numelems(A), and (if passed) numelems(B).
 • output: (optional) The type of output. The supported options are:
 – frequencies: Returns a Vector, of float[8] datatype and length size, containing the frequencies.
 – magnitudes: Returns a Vector of float[8] datatype and length size containing the magnitudes.
 – phases: Returns a Vector of float[8] datatype and length size containing the phases.
 – response: Returns a Vector of complex[8] datatype and length size containing the response. This is the default.
 – magnitudeplot: Returns a plot of the magnitudes versus the frequencies.
 – phaseplot: Returns a plot of the phases versus the frequencies.
 – record: Returns a record with the previous options.
 – list of any of the above options: Returns an expression sequence with the corresponding outputs, in the same order.

Description

 • The FilterFrequencyResponse command computes the frequency response of the transfer function indicated by the taps stored in one or two rtables/lists of 1-D data.
 • The A container stores the coefficients of the numerator of the transfer function and, if passed, B stores the coefficients of the denominator. Each of the containers must contain one or more elements.
 • For the IIR (Infinite Impulse Response) case, the impulse transfer function in terms of the taps is given by the following:

$H\left(z\right)=\frac{{\sum }_{k=1}^{m}{A}_{k}{z}^{k-1}}{{\sum }_{k=1}^{n}{B}_{k}{z}^{k-1}}$

 where $m=\mathrm{numelems}\left(A\right)$ and $n=\mathrm{numelems}\left(B\right)$. For the FIR (Finite Impulse Response) case:

$H\left(z\right)={\sum }_{k=0}^{m}{A}_{k}{z}^{k}$

 • Internally, the taps containers are padded with sufficiently-many zeros, if necessary, so that the response will be of length size.
 • When only numerator taps are passed (FIR case), the response is the Fast Fourier Transform (FFT) of the padded taps container. When denominator taps are also passed (IIR case), the response is the element-wise quotient of the FFTs of the respective padded taps containers. When the taps are all real-valued, the padded length will be 2*size, and then the redundant (due to symmetry) second half of any FFT will be discarded. On the other hand, when one or more taps is complex, the padded length will be just size, and no terms will be discarded.
 • The magnitudes are first computed as the element-wise absolute values of the response. Then, they are converted to decibels via the transformation $\mathrm{\rho }↦10\cdot {\mathrm{Typesetting}:-\mathrm{_Hold}\left(\left[\mathrm{%log}\right]\right)}_{10}\left(\mathrm{\rho }\right)$ for the complex case, and $\mathrm{\rho }↦20\cdot {\mathrm{Typesetting}:-\mathrm{_Hold}\left(\left[\mathrm{%log}\right]\right)}_{10}\left(\mathrm{\rho }\right)$ for the real-case (the extra factor of 2 is due to the symmetry and discarding of the second half of the FFTs).
 • The phases are first computed as the element-wise angles/arguments of the response. Then, they are "unwrapped" to eliminate big jumps in the phases, and finally, if phaseunit=degrees, converted to angles (a common convention).
 • When samplerate=NULL, the frequencies Vector $F$ is of size $n=\mathrm{size}$ and "normalized", with components defined by the following:

${F}_{k}=\frac{k-1}{n}$

 When $r=\mathrm{samplerate}$ is not NULL, on the other hand:

${F}_{k}=\frac{\left(k-1\right)r}{n}$

 • The samplerate option can include a unit, which will be included in the plots. Either of the forms algebraic or Unit(algebraic) is accepted, but the unit must be convertible to a valid unit of frequency.
 • Maple will attempt to coerce the provided taps to Vectors of complex[8] datatype, and an error will be thrown if this is not possible. For this reason, it is most efficient for the passed taps to use this datatype.
 • Input rtables cannot have an indexing function, and must use rectangular storage.
 • The FilterFrequencyResponse command is not thread safe.
 • As the underlying implementation of the SignalProcessing package is a module, it is also possible to use the form SignalProcessing:-FilterFrequencyResponse to access the command from the package. For more information, see Module Members.

Examples

 > $\mathrm{with}\left(\mathrm{SignalProcessing}\right):$

Simple Examples

 > $\mathrm{FilterFrequencyResponse}\left(\left[5,-3,7,1,10\right],\mathrm{size}=8\right)$
 $\left[\begin{array}{c}{5.}{+}{0.}{}{I}\\ {1.89019807578427}{-}{3.68139417593046}{}{I}\\ {-1.95710678118655}{-}{1.39644660940673}{}{I}\\ {-0.505419324478097}{+}{2.05114364039828}{}{I}\\ {2.}{+}{I}\\ {0.530545590325181}{-}{0.473982625448804}{}{I}\\ {-0.542893218813452}{+}{2.10355339059327}{}{I}\\ {3.08467565836865}{+}{3.79347955822245}{}{I}\end{array}\right]$ (1)
 > $F,R,M,P≔\mathrm{FilterFrequencyResponse}\left(\left[1,2-3I,4\right],\left[5,6-7I\right],\mathrm{samplerate}=2.5,\mathrm{size}=4,\mathrm{output}=\left[\mathrm{frequencies},\mathrm{response},\mathrm{magnitudes},\mathrm{phases}\right]\right)$
 ${F}{,}{R}{,}{M}{,}{P}{≔}\left[\begin{array}{c}{0.}\\ {0.625000000000000}\\ {1.25000000000000}\\ {1.87500000000000}\end{array}\right]{,}\left[\begin{array}{c}{0.576470588235294}{+}{0.0941176470588235}{}{I}\\ {0.600000000000000}{-}{0.800000000000000}{}{I}\\ {0.360000000000000}{-}{0.480000000000000}{}{I}\\ {0.0666666666666667}{+}{0.133333333333333}{}{I}\end{array}\right]{,}\left[\begin{array}{c}{-2.33510463907668}\\ {0.}\\ {-2.21848749616356}\\ {-8.26606256887672}\end{array}\right]{,}\left[\begin{array}{c}{9.27260177720030}\\ {-53.1301023541560}\\ {-53.1301023541560}\\ {63.4349488229220}\end{array}\right]$ (2)

Real FIR Filter

 • First, generate some FIR taps using the GenerateFIRFilterTaps command:
 > $\mathrm{Taps}≔\mathrm{GenerateFIRFilterTaps}\left(48,0.25,\mathrm{window}=\mathrm{Hamming},\mathrm{normalize}=\mathrm{false},\mathrm{filtertype}=\mathrm{lowpass}\right)$
 ${\mathrm{Taps}}{≔}\left[\begin{array}{cccccccccccccccccccccccccccccccccccccccccccccccc}{-0.000766226652048602}& {-0.000841339149671470}& {0.00100860740404767}& {0.00127911948879349}& {-0.00166460722830032}& {-0.00217769827899556}& {0.00283228559132624}& {0.00364406190199566}& {-0.00463129091647615}& {-0.00581592581011653}& {0.00722525069301681}& {0.00889433259851163}& {-0.0108697711579715}& {-0.0132156039368307}& {0.0160229476557357}& {0.0194264426666097}& {-0.0236338399613289}& {-0.0289828724473002}& {0.0360601225851508}& {0.0459783098573302}& {-0.0611288196507035}& {-0.0877401269135040}& {0.148669591060247}& {0.449695739487900}& {0.449695739487900}& {0.148669591060247}& {-0.0877401269135040}& {-0.0611288196507035}& {0.0459783098573302}& {0.0360601225851508}& {-0.0289828724473002}& {-0.0236338399613289}& {0.0194264426666097}& {0.0160229476557357}& {-0.0132156039368307}& {-0.0108697711579715}& {0.00889433259851163}& {0.00722525069301681}& {-0.00581592581011653}& {-0.00463129091647615}& {0.00364406190199566}& {0.00283228559132624}& {-0.00217769827899556}& {-0.00166460722830032}& {0.00127911948879349}& {0.00100860740404767}& {-0.000841339149671470}& {-0.000766226652048602}\end{array}\right]$ (3)
 • Now, display plots of the magnitude and phase of the response:
 > $\mathrm{num_points}≔1024$
 ${\mathrm{num_points}}{≔}{1024}$ (4)
 > $R≔\mathrm{FilterFrequencyResponse}\left(\mathrm{Taps},\mathrm{size}=\mathrm{num_points},\mathrm{output}=\mathrm{record}\right):$
 > $R\left[\mathrm{magnitudeplot}\right]$
 > $R\left[\mathrm{phaseplot}\right]$

IIR Filter

 • Here, we will obtain taps for a lowpass digital Chebyshev Type I Filter from the GenerateChebyshev1Taps command:
 > $\mathrm{cutoff_frequency_ratio}≔0.4$
 ${\mathrm{cutoff_frequency_ratio}}{≔}{0.4}$ (5)
 > $\mathrm{filter_order}≔5$
 ${\mathrm{filter_order}}{≔}{5}$ (6)
 > $\mathrm{ripple}≔29$
 ${\mathrm{ripple}}{≔}{29}$ (7)
 > $\mathrm{Taps}≔\mathrm{GenerateChebyshev1Taps}\left(\mathrm{filter_order},\mathrm{cutoff_frequency_ratio},\mathrm{ripple},\mathrm{filtertype}=\mathrm{lowpass}\right)$
 ${\mathrm{Taps}}{≔}\left[\begin{array}{cccccccccccc}{0.0145256222951220}& {0.0726281114756102}& {0.145256222951220}& {0.145256222951220}& {0.0726281114756102}& {0.0145256222951220}& {1.}& {1.67764328574172}& {1.12542851668154}& {-0.885659875792078}& {-1.51371985423053}& {-0.938872158956746}\end{array}\right]$ (8)
 • The first half of the Taps Vector are for the numerator, and the second half are for the denominator:
 > $A,B≔\mathrm{ListTools}:-\mathrm{Slice}\left(\mathrm{Taps},2\right)$
 ${A}{,}{B}{≔}\left[\begin{array}{cccccc}{0.0145256222951220}& {0.0726281114756102}& {0.145256222951220}& {0.145256222951220}& {0.0726281114756102}& {0.0145256222951220}\end{array}\right]{,}\left[\begin{array}{cccccc}{1.}& {1.67764328574172}& {1.12542851668154}& {-0.885659875792078}& {-1.51371985423053}& {-0.938872158956746}\end{array}\right]$ (9)
 • Now, we plot the magnitudes and phases of the response:
 > $\mathrm{num_points}≔1024$
 ${\mathrm{num_points}}{≔}{1024}$ (10)
 > $R≔\mathrm{FilterFrequencyResponse}\left(A,B,\mathrm{samplerate}=5.0\mathrm{Unit}\left(\mathrm{Hz}\right),\mathrm{size}=\mathrm{num_points},\mathrm{output}=\mathrm{record}\right):$
 > $R\left[\mathrm{magnitudeplot}\right]$
 > $R\left[\mathrm{phaseplot}\right]$

Complex FIR Filter

 > $n≔25$
 ${n}{≔}{25}$ (11)
 > $\mathrm{Taps}≔\mathrm{Vector}\left(n,k↦k+I\cdot {\left(-1\right)}^{k},\mathrm{datatype}=\mathrm{complex}\left[8\right]\right)$
 ${\mathrm{Taps}}{≔}\begin{array}{c}\left[\begin{array}{c}{1.}{-}{I}\\ {2.}{+}{I}\\ {3.}{-}{I}\\ {4.}{+}{I}\\ {5.}{-}{I}\\ {6.}{+}{I}\\ {7.}{-}{I}\\ {8.}{+}{I}\\ {9.}{-}{I}\\ {10.}{+}{I}\\ {⋮}\end{array}\right]\\ \hfill {\text{25 element Vector[column]}}\end{array}$ (12)
 > $\mathrm{num_points}≔2048$
 ${\mathrm{num_points}}{≔}{2048}$ (13)
 > $R≔\mathrm{FilterFrequencyResponse}\left(\mathrm{Taps},\mathrm{samplerate}=2.0,\mathrm{size}=\mathrm{num_points},\mathrm{phaseunit}=\mathrm{radians},\mathrm{output}=\mathrm{record}\right):$
 > $R\left[\mathrm{magnitudeplot}\right]$
 > $R\left[\mathrm{phaseplot}\right]$

Compatibility

 • The SignalProcessing[FilterFrequencyResponse] command was introduced in Maple 2021.