Expand description
§Parks-McClellan Remez FIR design algorithm
The pm_remez
crate is a modern implementation of the
Parks-McClellan Remez exchange algorithm. It supports the design of FIR
filters with even symmetry and odd symmetry, and with an even number of taps
and an odd number of taps, by reducing all these cases to the even symmetry
odd number of taps case. The desired frequency response in each band, as
well as the weights, can be defined as arbitrary functions. The crate
supports using
num-bigfloat
, or any
other high precision floating point package that implements the Float
trait for the calculations. This can be used to solve numerically
challenging problems that are difficult to solve using f64
arithmetic.
The implementation draws ideas from [2] to make the algorithm robust against numerical errors. These ideas include the use of Chebyshev proxy root finding to find the extrema of the weighted error function in the Remez exchange step.
§Examples
The main function of this crate is pm_remez
, which takes a
DesignParameters
object defining the filter to be constructed and
returns a PMDesign
struct containing the filter taps and other
information. There are two coding styles in which this function can be used.
The first style uses BandSetting
to define each band, setting the
desired response and weight separately on each band. The following
constructs a lowpass filter by setting the desired response to a
constant
of one in the passband and a constant of zero in the
stopband. Other kinds of reponses can be specified with linear
(linear
slope interpolating two values) and function
(arbitrary function). A
weight different from the default of constant(1.0)
can be provided with
BandSetting::with_weight
. The weight can be defined using constant
,
linear
or function
.
use pm_remez::{
constant, pm_parameters, pm_remez,
BandSetting, PMParameters, ParametersBuilder,
};
let bands = [
BandSetting::new(0.0, 0.2, constant(1.0))?,
BandSetting::new(0.3, 0.5, constant(0.0))?,
];
let num_taps = 35;
let parameters = pm_parameters(num_taps, &bands)?;
let design = pm_remez(¶meters)?;
The second style is closer to how the pm_remez
function is implemented. It
uses the PMParameters
struct to define a list of Band
s and the
desired response and weight as single functions for all the bands. The
pm_remez
function is generic in the types of the desired response and
weight functions, so this style can enable more compile time optimizations
by using monomorphization.
This designs the same lowpass filter using this second coding style.
use pm_remez::{pm_remez, Band, BandSetting, PMParameters};
let num_taps = 35;
let parameters = PMParameters::new(
num_taps,
vec![Band::new(0.0, 0.2)?, Band::new(0.3, 0.5)?],
|f| if f < 0.25 { 1.0 } else { 0.0 },
|_| 1.0,
)?;
let design = pm_remez(¶meters)?;
The documentation of the Python bindings
contains a series of examples that show how to use pm-remez to design
commonly used types of FIR filters. These examples are also useful to
understand how the Rust pm_remez
function can be used.
§Building
The pm_remez
crate uses ndarray_linalg
to solve eigenvalue problems.
This in turn depends on LAPACK. The pm_remez
crate has several feature
flags that are used to select the LAPACK backend. Exactly one of these
features needs to be enabled to build pm_remez
. The feature flags are
openblas-static
, openblas-system
, netlib-static
, netlib-system
,
intel-mkl-static
and intel-mkl-system
. The -static
versions of each
flag build the LAPACK backend and link statically against it. The -system
versions link against a system-installed library (linking can be dynamic or
static depending on which type of library is installed).
§References
[1] M. Ahsan and T. Saramaki, “Two Novel Implementations of the Remez Multiple Exchange Algorithm for Optimum FIR Filter Design”, MATLAB - A Fundamental Tool for Scientific Computing and Engineering Applications - Volume 2. InTech, Sep. 26, 2012.
[2] S.I. Filip. “A Robust and Scalable Implementation of the Parks-McClellan Algorithm for Designing FIR Filters,” in ACM Trans. Math. Softw. 43, 1, Article 7, March 2017.
[3] J. McClellan, T. Parks and L. Rabiner, “A computer program for designing optimum FIR linear phase digital filters,” in IEEE Transactions on Audio and Electroacoustics, vol. 21, no. 6, pp. 506-526, December 1973
[4] T. Parks and J. McClellan, “Chebyshev Approximation for Nonrecursive Digital Filters with Linear Phase,” in IEEE Transactions on Circuit Theory, vol. 19, no. 2, pp. 189-194, March 1972.
[5] B.N. Parlett and C. Reinsch, “Balancing a matrix for calculation of eigenvalues and eigenvectors”. Numer. Math. 13, 293–304 (1969).
Modules§
- Error types used by
pm_remez
.
Structs§
- Band.
- Band with desired response and weight
Setting
s. - A FIR filter design produced by the
pm_remez
function. - Parks-McClellan design parameters struct.
- Desired response or weight setting.
Enums§
- Symmetry of the FIR filter taps.
Traits§
- Parks-McClellan design parameters trait.
- Parks-McClellan design parameters setter trait.
- Conversion to a LAPACK-compatible scalar.
Functions§
- Creates a
Setting
that represents a constant function. - Creates a
Setting
that represents an arbitrary function. - Creates a
Setting
that represents a linear function. - Creates parameters for the Parks-McClellan algorithm in terms of a list of
BandSetting
s. - Parks-McClellan Remez exchange algorithm.