Crate pm_remez

source ·
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(&parameters)?;

The second style is closer to how the pm_remez function is implemented. It uses the PMParameters struct to define a list of Bands 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(&parameters)?;

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§

Enums§

  • Symmetry of the FIR filter taps.

Traits§

Functions§